Transitioning GitHub Actions Workflows to Ubuntu 24.04

The operational backbone of continuous integration and continuous delivery (CI/CD) pipelines relies heavily on the stability and consistency of the underlying execution environment. For developers utilizing GitHub Actions, the Linux operating system serves as the primary foundation for the majority of hosted runner workloads. The transition of the default ubuntu-latest label from Ubuntu 20.04 to Ubuntu 22.04, and subsequently to Ubuntu 24.04, represents a significant shift in the technical landscape for automation. This evolution is not merely a version increment; it involves changes in package availability, system architecture support, and compatibility with legacy software stacks. Understanding the mechanics of these transitions, the implications for specific development tools like Ansible and Python, and the architectural differences between hosted and self-hosted environments is critical for maintaining robust, failure-free pipelines.

The Lifecycle of Ubuntu Runner Images

GitHub-hosted runners are virtual machines that provide the execution environment for workflow jobs. These runners consume the free minutes allotted to a GitHub account or are charged at per-minute rates, depending on the repository type and usage. The lifecycle of an Ubuntu runner image is tied to the release and support lifecycle of the Ubuntu operating system itself. When a new major version of Ubuntu becomes generally available, GitHub updates its hosted runner images to reflect this change.

The ubuntu-latest label is a dynamic pointer that changes over time. Historically, ubuntu-latest pointed to Ubuntu 20.04. As Ubuntu 22.04 became generally available on GitHub-hosted runners, GitHub recommended the use of ubuntu-latest because it would automatically transition to the newer OS version in the near future, removing the need for manual updates to workflow files. However, this automatic transition can introduce unexpected breaks in workflows that rely on specific software versions present in the older image but removed or altered in the newer one.

The rollout of Ubuntu 24.04 followed a structured timeline. It was available in preview mode starting in May 2024 and became generally available for all customers in July 2024. The decision to set Ubuntu 24.04 as the default for the ubuntu-latest label was driven by the need to maintain service level agreements (SLAs) for free disk space and to incorporate improved image stability based on customer feedback. The rollout began on December 5th, 2024, and was completed on January 17th, 2025. This means that any workflow using runs-on: ubuntu-latest will now execute on an Ubuntu 24.04 image, unless explicitly pinned to an older version like ubuntu-22.04 or ubuntu-20.04.

Virtual Machine Processor (CPU) Memory (RAM) Storage (SSD) Architecture Workflow Label
Linux 1 5 GB 14 GB x64 ubuntu-slim
Linux 2 8 GB 14 GB x64 ubuntu-latest, ubuntu-24.04, ubuntu-22.04
Windows 2 8 GB 14 GB x64 windows-latest, windows-2025, windows-2022
Linux 2 8 GB 14 GB arm64 ubuntu-24.04-arm, ubuntu-22.04-arm
Windows 2 8 GB 14 GB arm64 windows-11-arm
macOS 4 14 GB 14 GB Intel macos-15-intel, macos-26-intel
macOS 3 (M1) 7 GB 14 GB arm64 macos-latest, macos-14, macos-15, macos-26

The ubuntu-slim image is a specialized variant with only 1 CPU core and 5 GB of RAM, designed for minimal resource consumption. In contrast, the standard Ubuntu images provide 2 CPU cores and 8 GB of RAM. The storage capacity for all Linux and Windows runners is 14 GB, which imposes strict constraints on the size of the tools and packages that can be pre-installed on the image.

Compatibility Challenges and Legacy Software Support

The transition to newer Ubuntu versions often results in breaking changes for workflows that depend on legacy software. One of the most significant impacts has been on the testing and deployment of older Python versions and specific versions of Ansible.

Developers who need to test software against Python 3.6 have faced difficulties with newer Ubuntu images. The actions/setup-python action, which is used to install specific Python versions, encountered issues on Ubuntu 22.04 and subsequent versions when attempting to set up Python 3.6 without using a Docker container. This is because the underlying system libraries and dependencies required by Python 3.6 are no longer available or are incompatible with the newer Ubuntu base images. Consequently, developers relying on Python 3.6 testing must explicitly use ubuntu-20.04 in their workflow files to ensure compatibility. If GitHub drops support for ubuntu-20.04 entirely, testing against Python 3.6 in GitHub Actions may become impossible without resorting to containerized environments.

Similarly, the Ansible community has highlighted significant challenges with running Ansible tests on newer Ubuntu images. The ansible-test tool, which is used to validate Ansible collections and modules, often requires specific system conditions such as cgroups v2 support and certain versions of SSH and init systems. Ansible-core 2.12 and later versions support cgroups v2, which is a feature available in Ubuntu 22.04 and 24.04. However, older versions of Ansible, such as 2.9, ansible-base 2.10, and ansible-core 2.11, require the ubuntu-20.04 image for their Docker-based tests to function correctly. The ansible-test --docker command, which spins up Docker containers for testing, can fail on ubuntu-latest if the image does not provide the necessary dependencies or if the cgroup version is incompatible.

For organizations that need to maintain compatibility with these older versions, the recommended approach is to explicitly specify the older Ubuntu version in the workflow file, such as runs-on: ubuntu-20.04. However, this is a temporary solution. As Ubuntu 20.04 reaches the end of its standard support in April 2025, the viability of this approach diminishes. While paid extended support is available until April 2030, relying on an unsupported OS for CI/CD pipelines introduces security and stability risks.

Network Configuration and Runner Connectivity

GitHub-hosted runners are distributed across multiple cloud providers to ensure high availability and performance. Windows and Ubuntu runners are hosted in Microsoft Azure, while macOS runners are hosted in GitHub's own macOS cloud. This distribution has implications for network configuration, particularly for organizations with strict firewall rules or internal resources that need to be accessed by the CI/CD pipelines.

The IP address ranges used by GitHub-hosted runners are not static. They change frequently due to the dynamic nature of cloud infrastructure. To identify the current IP address ranges, developers can use the GitHub REST API, specifically the GET /meta endpoint, which returns a list of IP ranges under the actions key. This list is updated once a week. However, using these dynamic IP ranges as allowlists for internal resources is generally discouraged due to the complexity and maintenance overhead involved.

For organizations that require more predictable network access, GitHub recommends using larger runners with static IP address ranges or self-hosted runners. Self-hosted runners allow developers to have full control over the network configuration, security policies, and installed software. This approach is particularly useful for workflows that need to interact with internal networks, legacy systems, or proprietary tools that cannot be exposed to the public internet.

A critical aspect of runner connectivity is the need for the runner to establish connections to GitHub-owned endpoints for essential communication operations. This includes fetching workflow definitions, uploading artifacts, and reporting job status. Additionally, runners may need access to external networks specified within the workflow, such as package repositories, artifact storage, or external APIs. To ensure proper communication, organizations must configure their firewalls to allow traffic to these endpoints. Some of the domains used by GitHub Actions are configured using CNAME records, which can complicate firewall rules. In such cases, firewalls may need to be configured to recursively resolve and allow traffic to all CNAME records associated with the primary domain.

Arm64 Architecture and Partner Images

The introduction of Ubuntu 24.04 on GitHub-hosted runners also brought support for the arm64 architecture. Developers can now run their Actions workflows on Ubuntu 24.04 using GitHub-hosted arm64 runners, which are currently in public beta. This expansion allows for better testing and deployment of applications that target ARM-based hardware, such as mobile devices, embedded systems, and cloud instances optimized for energy efficiency.

To utilize the arm64 runner, developers must create an arm64 runner in their organization or enterprise and select the "Ubuntu 24.04 by Arm Limited" partner image. The workflow file must then be updated to specify the correct runner label, such as runs-on: ubuntu-24.04-arm. It is important to note that this specific image is provided and maintained by Arm Limited, not by GitHub. If developers encounter issues with their workflows or have feedback on the software installed on the image, they should direct their inquiries to the partner-runner-images repository.

While all actions provided by GitHub are compatible with arm64 runners, community actions may not be. Some community actions may rely on x64-specific binaries or libraries, requiring manual installation or adaptation to run on arm64. This necessitates careful testing and potential modification of workflow files when migrating to arm64 runners.

Managing Package Removals and Disk Space Constraints

The transition to Ubuntu 24.04 as the default ubuntu-latest image involved significant changes to the set of pre-installed packages. GitHub made deliberate cuts to the list of packages included in the Ubuntu 24.04 image to maintain its service level agreement for free disk space. The 14 GB SSD storage limit imposes strict constraints on the size of the runner image, forcing GitHub to prioritize essential tools and remove less commonly used packages.

Developers should review the list of removed packages carefully to determine if their workflows will be impacted. If a workflow relies on a package that has been removed, it must be updated to install the package manually within the workflow steps. This can be done using shell commands to install the package from Ubuntu's repositories or from external sources. For example, if a workflow requires a specific version of a development tool that is no longer pre-installed, a step can be added to the workflow file to install it:

- name: Install required package run: sudo apt-get update && sudo apt-get install -y package-name

This manual installation step adds overhead to the workflow execution time but ensures that the required software is available. It is crucial for developers to understand that the set of tools and tool versions in the Ubuntu 24.04 runner image differs from that of Ubuntu 20.04 and 22.04. Assuming that a tool is available because it was present in a previous version can lead to workflow failures.

Best Practices for Workflow Stability

To mitigate the risks associated with transitioning to newer Ubuntu versions, developers should adopt several best practices. First, explicitly specify the Ubuntu version in the workflow file rather than relying on ubuntu-latest. This ensures that the workflow runs on a known, stable version of the OS until the developer is ready to migrate to the newer version. For example:

jobs: build: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 - name: Build run: dotnet build - name: Run tests run: dotnet test

Second, regularly update workflow files to test against newer Ubuntu versions in a non-production environment. This allows developers to identify and fix compatibility issues before they affect production workflows. Third, utilize Docker containers within GitHub Actions to encapsulate the build and test environment. This provides greater control over the software versions and dependencies, reducing the impact of changes to the underlying runner image.

Fourth, for workflows that require legacy software support, consider using self-hosted runners with older Ubuntu versions. This approach allows organizations to maintain support for older software while still leveraging GitHub Actions for CI/CD. However, self-hosted runners require additional maintenance and security oversight.

Finally, stay informed about upcoming changes to GitHub-hosted runners by monitoring the GitHub Blog and the runner-images repository. GitHub provides advance notice of changes, such as the rollout of new Ubuntu versions, allowing developers to prepare for potential disruptions.

Conclusion

The evolution of GitHub Actions runner images from Ubuntu 20.04 to 24.04 represents a significant shift in the CI/CD landscape for developers. While the transition offers access to newer software and improved performance, it also introduces challenges related to compatibility, network configuration, and disk space constraints. Developers must be proactive in managing these changes by explicitly specifying runner versions, testing for compatibility, and leveraging containerization or self-hosted runners when necessary. Understanding the technical details of each runner image, including the specific tools and architectures supported, is essential for maintaining robust and reliable automation pipelines. As GitHub continues to update its hosted runners, the ability to adapt workflows to these changes will be a critical skill for development teams.

Sources

  1. GitHub Actions Ubuntu 24.04 Image Now Available for Arm64 Runners
  2. Workflow with runs-on: ubuntu-20.04 actually runs on Ubuntu 22.04
  3. GitHub Actions Ubuntu 22.04 is Now Generally Available on GitHub-Hosted Runners
  4. GitHub-Hosted Runners Documentation
  5. GitHub Actions Still Using Ubuntu 20.04
  6. Ubuntu-latest Workflows Will Use Ubuntu-24.04 Image

Related Posts