RLC Cloud Repos is a cloud-init-powered, cloud-agnostic repository configuration utility designed to:
- Automatically configure DNF/YUM repositories for Rocky Linux by CIQ (RLC) instances in the Cloud.
- Dynamically select the best repository mirror based on cloud provider and region.
- Integrate with Cloud-Init, ensuring repo configuration happens early in the boot process.
- Deploy updates via RPM packaging, making it easy to manage at scale.
Deploying and Running Rocky Linux on multiple cloud providers (AWS, Azure, GCP, OCI) requires custom repository configuration:
- Mirrors vary per provider and region.
- Network performance and bandwidth metering demand regional proximity.
- Instance metadata varies widely.
- Fallbacks when a mirror is unavailable (e.g., AWS instances in
us-west-1fallback tous-east-1). - Ensuring Cloud-Init properly integrates the repository configurations during instance boot.
- Zero-Touch Configuration – Just boot the VM and it configures itself.
- Performance-Aware – Selects pre-configured available mirror.
- Cloud-Native – Leverages
cloud-init query, not hand-coded API logic. - Dynamic and Safe – Uses a marker file to prevent reconfig unless explicitly allowed or on package update.
The system is designed as modular components that work together to detect cloud provider, determine region, configure repositories, and integrate with Cloud-Init.
+----------------------------+
| Instance Boot |
+----------------------------+
|
v
+--------------------------------+
| Detect Cloud Provider & Region |
| via cloud-init |
+--------------------------------+
|
v
+----------------------------+
| Select Primary + Backup |
| Mirrors from region map |
+----------------------------+
|
v
+----------------------------+
| Configure DNF Variables |
| in /etc/dnf/vars/ |
+----------------------------+
|
v
+----------------------------+
| Touch marker file to skip |
| reconfiguration next boot |
+----------------------------+
- Uses
cloud-init queryto fetch:- Provider name
- Region
- Exits early with an error if cloud-init query fails or is unavailable.
- Generates DNF Variables from cloud-init metadata.
- Supports:
- Primary mirror
- Backup mirror
- Region
- Maps variables against
ciq-mirrors.yamlmatrix - CasC (Configuration As Code) Versioned.
- No code changes required for any mirror changes.
- Entry point triggered by cloud-init or manual run.
- Checks for marker file to skip duplicate configuration.
- Writes a marker file once run to prevent recurrent reconfiguring at reboot.
To generate the source tarball used for packaging:
make sdistThis will produce a .tar.gz source archive in the dist/ directory, suitable for consumption by downstream RPM packaging workflows.
rlc-cloud-reposThis will:
- Detect cloud metadata using
cloud-init query - Write marker file to skip reconfig on next boot
The following providers are supported natively via cloud-init metadata detection:
- AWS
- Azure
- Google Cloud Platform (GCP)
- Oracle Cloud Infrastructure (OCI)
Mirror mapping is handled via a region → mirror YAML file (ciq-mirrors.yaml) shipped in the package.
- Mirror selection logic is data-driven via
ciq-mirrors.yaml - Configuration persists indefinitely until removed/updated.
RLC Cloud Repos includes a plugin system designed for repository owners and maintainers who need to integrate non-standard or add-on DNF repositories with the cloud-aware repository configuration system.
This system allows repository providers to:
- Add custom DNF variables specific to their repository infrastructure
- Integrate with cloud-aware repository selection without modifying core RLC Cloud Repos code
- Support repository-specific metadata or authentication requirements
- Extend repository configurations based on cloud provider/region combinations
Repository plugins are executable files placed in /etc/rlc-cloud-repos/plugins.d/ and must:
- Be executable (
chmod +x) - Be owned by root
- Not be world-writable
- Not end with ignore patterns:
.ignore*,.disable*,.bak,.backup,.rpm*
Plugins can be written in any language (shell, Python, Perl, Go, etc.) as long as they are executable.
Plugins receive cloud metadata as command-line arguments, defined currently as:
--provider- Cloud provider name (aws, azure, gcp, etc.)--region- Cloud region--primary-url- Primary mirror URL selected by RLC--backup-url- Backup mirror URL selected by RLC
Parameter Usage: Plugins may use any or none of the defined parameters, but must accept all unrecognized and unused parameters without erroring. Unrecognized parameters must be ignored.
Output Format: Repository plugins should output key=value pairs to stdout for any additional DNF variables needed by their repositories.
Protected Variables: Plugins cannot override the following core DNF variables managed by RLC Cloud Repos:
baseurl1- Primary mirror URLbaseurl2- Backup mirror URLcontentdir- Content directory pathproduct- Product identifiercloudcontentdir- Cloud content directory path
Attempts to set these variables will be ignored and logged as warnings.
Error Handling Contract:
- Exit Code 0: Success - Plugin executed successfully, any stdout output will be processed
- Exit Code > 0: Error - Plugin failed, stdout output will be ignored
- stderr Output: Error messages and logging - Will be captured and logged by RLC for debugging
Forward Compatibility Requirement: Plugins must gracefully handle unknown command-line arguments without error. Future versions of RLC Cloud Repos may pass additional arguments, and plugins should ignore unrecognized options to maintain compatibility.
Two plugin templates are available after package installation to help repository maintainers integrate with RLC's cloud-aware configuration:
Simple Template - Basic functionality:
/usr/share/doc/rlc-cloud-repos/simple.sh.template
Complete Template - Comprehensive examples with advanced features:
/usr/share/doc/rlc-cloud-repos/complete.sh.template
Repository maintainers can choose the appropriate template based on their integration needs.
# Repository maintainers would typically distribute plugins via their RPM packages
# which would install to /etc/rlc-cloud-repos/plugins.d/
# Then set up a soft requirement (recommends) on python3-rlc-cloud-repos
# For development/testing - use simple template:
sudo cp /usr/share/doc/python3-rlc-cloud-repos/simple.sh.template \
/etc/rlc-cloud-repos/plugins.d/my-repo.sh
# Or use complete template for advanced features:
sudo cp /usr/share/doc/python3-rlc-cloud-repos/complete.sh.template \
/etc/rlc-cloud-repos/plugins.d/my-repo.sh
# Make executable and customize for repository needs
sudo chmod 755 /etc/rlc-cloud-repos/plugins.d/my-repo.shPlugins execute after core RLC repository configuration, allowing repository providers to layer additional DNF variables or repository-specific configurations on top of the base cloud-aware setup.
- Touch file at
/etc/rlc-cloud-repos/.configuredused to block rerun - Logs only to stdout/stderr
- The included RPM spec (rpm/python3-rlc-cloud-repos.spec) handles the marker file lifecycle:
- Creates the marker file on initial install (%post).
- Removes the marker file on upgrade (%posttrans) and uninstall (%postun) to allow reconfiguration.
Create branches off of git@github.com:ctrliq/rlc-cloud-repos.git Branch: main
to develop PRs.
Create and activate a virtual environment:
python3 -m venv venv
source venv/bin/activateInstall development dependencies:
make devRun tests:
make testRLC Cloud Repos is licensed under the MIT License.
CIQ Automation and Delivery Team https://github.com/ctrliq/rlc-cloud-repos