Introduction
Red Hat Satellite (and its upstream project Foreman) is the enterprise platform for lifecycle management of RHEL hosts — provisioning, patching, content management, and compliance. The theforeman.foreman Ansible collection provides a dynamic inventory plugin and 70+ modules to automate every Satellite/Foreman operation. This guide covers inventory integration, host provisioning, content view management, patching workflows, and compliance reporting.
Prerequisites
# Install the collection
ansible-galaxy collection install theforeman.foreman
# Dependencies
pip install requests
Satellite Credentials
# group_vars/all/satellite.yml (vault-encrypted)
satellite_url: https://satellite.example.com
satellite_username: admin
satellite_password: "{{ vault_satellite_password }}"
satellite_organization: "My Organization"
satellite_location: "Default Location"
Dynamic Inventory from Satellite
Basic Configuration
# satellite_inventory.foreman.yml
plugin: theforeman.foreman.foreman
url: https://satellite.example.com
user: admin
password: "{{ lookup('env', 'SATELLITE_PASSWORD') }}"
validate_certs: true
# Group by Satellite attributes
group_prefix: satellite_
want_hostcollections: true
want_params: true
# Only active hosts
want_facts: true
# Use Satellite host groups as Ansible groups
hostgroup_separator: "_"
export SATELLITE_PASSWORD=secret
ansible-inventory -i satellite_inventory.foreman.yml --graph
Advanced Inventory
# satellite_inventory.foreman.yml
plugin: theforeman.foreman.foreman
url: https://satellite.example.com
user: admin
password: "{{ lookup('env', 'SATELLITE_PASSWORD') }}"
validate_certs: true
# Groups from Satellite
want_hostcollections: true
want_params: true
want_facts: true
want_content_facet_attributes: true
want_organization: true
want_location: true
# Map Satellite fields to Ansible vars
compose:
ansible_host: ip
# Custom groups
groups:
rhel9: "'RHEL 9' in content_facet_attributes.content_view_name | default('')"
patching_window_1: "'patch-window-1' in hostcollection | default([])"
keyed_groups:
- key: hostgroup_title | default('ungrouped')
prefix: hg
- key: lifecycle_environment_name | default('Library')
prefix: env
- key: content_view_name | default('Default')
prefix: cv
Host Provisioning
Create Host
---
- name: Provision hosts via Satellite
hosts: localhost
gather_facts: false
tasks:
- name: Create host in Satellite
theforeman.foreman.host:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
validate_certs: true
name: "{{ item.name }}"
organization: "{{ satellite_organization }}"
location: "{{ satellite_location }}"
hostgroup: "RHEL9/WebServers"
compute_resource: "VMware vCenter"
compute_profile: "Medium"
content_source: "{{ satellite_url | urlsplit('hostname') }}"
lifecycle_environment: "Production"
content_view: "RHEL9-WebServer"
build: true
state: present
loop:
- { name: "web01.example.com" }
- { name: "web02.example.com" }
- { name: "web03.example.com" }
Create Host Group
- name: Create host group
theforeman.foreman.hostgroup:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
name: "RHEL9/WebServers"
organization: "{{ satellite_organization }}"
locations:
- "{{ satellite_location }}"
lifecycle_environment: "Production"
content_view: "RHEL9-WebServer"
puppet_proxy: ""
domain: "example.com"
subnet: "Production-10.0.1.0/24"
architecture: "x86_64"
operatingsystem: "RHEL 9.4"
medium: "RHEL9"
partition_table: "Kickstart default"
root_pass: "{{ vault_root_password }}"
state: present
Content View Management
Create Content View
- name: Create content view
theforeman.foreman.content_view:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
organization: "{{ satellite_organization }}"
name: "RHEL9-WebServer"
repositories:
- name: "Red Hat Enterprise Linux 9 for x86_64 - BaseOS RPMs 9"
product: "Red Hat Enterprise Linux for x86_64"
- name: "Red Hat Enterprise Linux 9 for x86_64 - AppStream RPMs 9"
product: "Red Hat Enterprise Linux for x86_64"
state: present
- name: Publish content view
theforeman.foreman.content_view_version:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
organization: "{{ satellite_organization }}"
content_view: "RHEL9-WebServer"
lifecycle_environments:
- Library
state: present
Promote Content View
- name: Promote content view to Production
theforeman.foreman.content_view_version:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
organization: "{{ satellite_organization }}"
content_view: "RHEL9-WebServer"
current_lifecycle_environment: "Testing"
lifecycle_environments:
- Production
state: present
Patching Workflow
Scheduled Patching via Satellite
---
- name: Patch RHEL hosts via Satellite
hosts: satellite_patching_window_1
become: true
serial: "25%"
max_fail_percentage: 10
tasks:
- name: Pre-patch — check services
ansible.builtin.service_facts:
- name: Pre-patch — create snapshot
theforeman.foreman.host_power:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
name: "{{ inventory_hostname }}"
state: state # Get current state
delegate_to: localhost
register: host_state
- name: Install all available errata
ansible.builtin.dnf:
name: '*'
state: latest
update_cache: true
register: patch_result
- name: Reboot if kernel updated
ansible.builtin.reboot:
reboot_timeout: 600
when: patch_result.changed and 'kernel' in (patch_result.results | default([]) | join(' '))
- name: Post-patch — verify services
ansible.builtin.service_facts:
- name: Post-patch — verify key services running
ansible.builtin.assert:
that:
- ansible_facts.services['sshd.service'].state == 'running'
fail_msg: "Critical service not running after patching"
- name: Update Satellite host facts
theforeman.foreman.host:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
name: "{{ inventory_hostname }}"
state: present
delegate_to: localhost
Errata Management
- name: Apply specific errata
theforeman.foreman.host_errata:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
host: "{{ inventory_hostname }}"
errata:
- "RHSA-2026:1234"
- "RHSA-2026:5678"
state: present
delegate_to: localhost
Activation Keys
- name: Create activation key
theforeman.foreman.activation_key:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
organization: "{{ satellite_organization }}"
name: "RHEL9-WebServer-Prod"
lifecycle_environment: "Production"
content_view: "RHEL9-WebServer"
auto_attach: true
host_collections:
- "WebServers"
state: present
Compliance Reporting
- name: Generate compliance report
hosts: localhost
gather_facts: false
tasks:
- name: Get all hosts with outdated packages
theforeman.foreman.resource_info:
server_url: "{{ satellite_url }}"
username: "{{ satellite_username }}"
password: "{{ satellite_password }}"
resource: hosts
search: "applicable_errata > 0"
register: outdated_hosts
- name: Display hosts needing patches
ansible.builtin.debug:
msg: "{{ item.name }}: {{ item.content_facet_attributes.errata_counts | default({}) }}"
loop: "{{ outdated_hosts.resources }}"
loop_control:
label: "{{ item.name }}"
Troubleshooting
API Connection Failed
# Test API connectivity
curl -k -u admin:password https://satellite.example.com/api/v2/status
Inventory Empty
- Verify hosts have
Managedflag set in Satellite - Check organization/location permissions for the API user
- Verify
validate_certsmatches your SSL setup
Slow Inventory
# Enable caching
plugin: theforeman.foreman.foreman
cache: true
cache_plugin: jsonfile
cache_connection: /tmp/satellite-cache
cache_timeout: 1800
Related Articles
- Ansible Automation Platform 2.6
- Ansible RHEL 10 Migration
- Ansible Compliance
- Ansible Dynamic Inventory
Conclusion
Satellite/Foreman plus Ansible creates a complete RHEL lifecycle management platform. The dynamic inventory plugin groups hosts by hostgroup, lifecycle environment, content view, and host collections — ready for targeted patching, provisioning, and compliance workflows. Use theforeman.foreman modules to automate content view publishing and promotion, host provisioning via compute resources, and errata management across thousands of RHEL hosts.