Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to manage Python dependencies in Ansible execution environments

January 27, 2025
Andrew Block
Related topics:
ContainersPython
Related products:
Red Hat Ansible Automation Platform

Share:

    Ansible execution environments provide a runtime for Red Hat Ansible Automation Platform that includes all of the necessary tooling in a single atomic package. Ansible, as an automation tool, relies on Python as its underlying programming language. Not only is Python integral to the core of Ansible, but its use is widespread and can be found throughout the Ansible ecosystem, including Ansible execution environments. As a result, how Python content is managed directly impacts how an execution environment is constructed and operates at runtime. This article will explore the various ways that Python can be managed in Ansible execution environments, including considerations that apply to a variety of operating environments.

    Python within execution environments

    An Ansible execution environment is a container image, and its construction is expressed within a definition file (by default with the name execution-environment.yml) which enables operating system packages, Python content, Ansible dependencies, and other configurations to be specified. Multiple options are available within the execution environment definition to enable end users to manage how the base Python package is configured within the underlying operating system, but also how Python packages and any other dependencies are handled.

    The dependencies section of the execution environment definition file contains several properties that users can customize the use of Python along with any related content. The underlying Python package that the execution environment relies on is defined within the dependencies.python_interpreter property. Two options are available within the python_interpreter property:

    1. package_system: Python package managed by the operating system package manager (such as dnf).
    2. python_path: Location of the Python interpreter.

    An example of how these properties can be defined within an execution environment definition file is shown below:

    ---
    version: 3
    
    ...
    
    dependencies:
      python_interpreter:
        package_system: "python310"
        python_path: "/usr/bin/python3.10" 

    Python dependency management

    The management of Python packages is facilitated using the pip package manager. pip takes on responsibility for managing core Ansible execution environment components, including ansible-core and ansible-runner, as well as dependencies declared by Ansible Content Collections along with any user-defined packages.

    Customizations to the Ansible Core and Ansible Runner packages can be defined by specifying the following underneath the dependencies within the execution environment definition file:

    ---
    version: 3
    
    ...
    
    dependencies:
      ansible_core:
        package_pip: ansible-core==2.14.2
      ansible_runner:
        package_pip: ansible-runner==2.3.1

    While users have the ability to customize how the underlying Python package and core Ansible components that are managed within an execution environment are defined, most end users will be concerned with how to specify additional Python packages that should also be included within an execution environment. These packages are used primarily by Ansible Content Collections that are also included within an execution environment, as are any other components that rely on Python content.

    User-defined Python dependencies can either be explicitly defined within the execution environment definition file or via a reference to a file (typically specified within a file called requirements.txt) containing the dependencies to install. The dependencies.python property within the execution environment definition file is the location where either of these approaches are declared. 

    The following example illustrates how to explicitly declare the desired Python dependencies within the execution environment definition file:

    ---
    version: 3
    
    ...
    
    dependencies:
      # Explicitly declaring Python dependencies
      python:
        - jmespath

    Alternatively, dependencies declared within an external file can be referenced within an execution environment definition file, and can be specified using the following:

    ---
    version: 3
    
    ...
    
    dependencies:
      # Referencing an external file containing Python dependencies
      python: requirements.txt

    Regardless of the approach selected, Ansible execution environments offer options for Ansible creators to choose the approach that suits them best.

    Build time considerations

    Thus far, we have discussed several methods for how to define Python-related content that is included within Ansible execution environments. In this section, we will build upon those skills and explore how this Python content is managed during the build process of an execution environment, including the ways that you can influence the final image that is produced as a result of the build.

    When an execution environment is being built, it undergoes several stages where the resulting content is used to assemble the final image. (You can learn more about the execution environment build stages and the actions the ansible-builder tool performs here). Several of these stages have activities directly related to how Python content is utilized and sourced from remote locations. The properties that were defined earlier, such as Python executable version and location, are utilized throughout this process. The additional_build_steps property of the execution environment definition file provides the constructs for users to add customized logic (in the form of commands that are processed by the container tool, such as Podman, in use) within the build process, and is where any of the activities related to the management of Python content can be made. The builder stage of the execution environment build process is primarily where Python-related activities occur including the resolution of declared dependencies and is where any customizations should take place. The base and final stages also play a role in how Python content is assembled into the final image.

    As an Ansible creator, there are at least two primary use cases (though there are certainly others as well) for which there may be a need to interject in the default build of an execution environment:

    1. Upgrading core pip components.
    2. Sourcing of Python dependencies managed by pip.

    Similar to how there is a need to ensure that Python and any of the libraries needed to support Ansible automation (as well as the underlying operating system) within an execution environment are updated, it is also important that pip and any of the tooling that it relies upon (such as setuptools) is up to date as well. Let’s show how we can verify that the latest version of both pip and setuptools are included within the execution environment.

    For this task, we will add a new step just prior to when actions in the base stage are executed. The additional_build_steps property offers the prepend_base option to enable additional commands to accomplish this goal. See below:

    ---
    version: 3
    ...
    
    additional_build_steps:
      prepend_base:
        - RUN $PYCMD -m pip install --upgrade pip setuptools

    RUN is an instruction of the container tool to execute commands and $PYCMD is one of several environment variables that are exposed throughout the build process by the ansible-builder tool. $PYCMD refers to the location of the Python binary, and as you can see, it is being used here to upgrade both pip and setuptools packages to their latest versions to provide a solid foundation for Python content to build upon.

    With an assurance that the base Python content within an execution environment is updated, focus can then shift to the management of dependencies as declared by the user. By default, Python dependencies are sourced from Python Package Index (PyPi), a public hosted repository containing Python content. The ability to easily reference content from a public service is beneficial, as it simplifies how Python content is sourced. However, in many enterprise organizations, they establish and leverage their own internal repository (similar to PyPi) to govern the type of content that can be used. Access to the public PyPi repository is typically restricted or even forbidden. In these situations and environments, ansible-builder must be instructed to source content from this alternate location.

    The pip utility provides options at package install time for referencing locations other than the public PyPi repository which contain Python packages. They can be explicitly set via command line arguments. However, similar to what we saw previously, it is easier to make use of environment variables, as it reduces the overall complexity for specifying different configurations.

    The following environment variables can be set to influence how pip sources Python content:

    • PIP_INDEX_URL: Location of the PEP 503 compliant repository (the default location is here).
    • PIP_TRUSTED_HOST: Explicitly trust the host defined. Useful when operating in environments that leverage their own Certificate Authority (CA) for managing Secure Sockets Layer (SSL) certificates which may not be trusted by the default configuration of the base execution environment being used as the foundation for the new execution environment.

    These variables can be placed as needed, and are leveraged within the builder and final stages of an execution environment build. To ensure they are defined before starting those stages, we can use the prepend_builder and prepend_final of the additional_build_steps property to inject those environment variables, as shown below:

    ---
    version: 3
    ...
    
    additional_build_steps:
      prepend_builder:
        - ENV PIP_INDEX_URL=https://myprivatrepohost/pythonrepo/simple
      prepend_final:
        - ENV PIP_INDEX_URL=https://myprivatrepohost/pythonrepo/simple

    If authentication is required to access content from the repository, credentials can be provided (especially if utilizing basic authentication) as part of the URL using the form https://<username>:<password>@myprivatrepohost/pythonrepo/simple and replacing the <username> and <password> placeholders with their actual values.

    Alternatively, instead of specifying credentials within the URL, support is available within pip to authenticate using alternate sources, including a .netrc file or a keyring. The configurations needed go beyond the scope of this article, but the inclusion here highlights the options that are available for accessing protected repositories.

    Another enhancement that can be made is to make use of Dockerfile/Containerfile arguments using the ARG instruction instead of the ENV instruction. This offers the flexibility to reuse the same execution environment definition file among multiple environments where Python dependencies may be sourced from different locations (such as between development and production environments).

    The following execution environment file depicts the changes necessary to transition from ENV to ARG instructions:

    ---
    version: 3
    ...
    
    additional_build_steps:
      prepend_builder:
        - ARG PIP_INDEX_URL
      prepend_final:
        - ARG PIP_INDEX_URL

    At execution environment build time, values can be injected by specifying the --build-arg flag when invoking the ansible-builder build command. For example, to replicate the first example where the ENV instruction is being utilized, the following command can be used:

    ansible-builder build --build-arg=PIP_INDEX_URL=https://myprivatrepohost/pythonrepo/simple <additional arguments>

    A useful feature of the ansible-builder utility is that if the environment variable is already defined in the current shell, it will automatically be injected into the value of the build argument being specified (--build-arg=PIP_INDEX_URL).

    Conclusion

    In this article, I described the various ways that Python-related content can be managed when building Ansible execution environments. From the ability to define the base Python components to the management of Python dependencies, these approaches afford Ansible creators the opportunity to customize and tune the build process such that Ansible execution environments can be utilized across a variety of operating environments.

    Interested in learning more about building and utilizing Ansible execution environments in your own automation workflows? Explore both the associated documentation as well as interactive exercises to level up your skills below.

    Documentation:

    • Creating and Using Ansible Execution Environments
    • Using Ansible Content Navigator

    Interactive exercises:

    • Getting started with Ansible Builder
    • Getting started with Ansible Navigator

    Related Posts

    • Strategies for eliminating Ansible hardcoded credentials

    • How to create execution environments using ansible-builder

    • How to install Microsoft SQL on RHEL using ansible-navigator

    • How to build virtual machines using Ansible Collections

    • Use the Kubernetes Python client from your running Red Hat OpenShift pods

    Recent Posts

    • Container starting and termination order in a pod

    • More Essential AI tutorials for Node.js Developers

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    What’s up next?

    With growing threats and attack vectors, implementing Zero Trust across your organization is an imperative. Read Build a foundation of security with Zero Trust and automation to find out more about the Zero Trust model and how to automate it.

    Get the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue