Linux Server JFrog Repository Configuration
Linux Server JFrog Repository Configuration
Overview
This document describes the JFrog SaaS repository configuration for RHEL 9 Linux servers in the Epic on Azure environment. The configuration migrates servers from the legacy unified uhc.repo to a split repository model with JFrog SaaS repositories and Red Hat Satellite repositories.
Architecture
Repository Structure
After configuration, Linux servers will have three repository files:
-
satellite.repo - Red Hat core repositories via CIMS Satellite
rhel-9-for-x86_64-baseos-cims-rpms- BaseOS packagesrhel-9-for-x86_64-appstream-cims-rpms- AppStream packagesrhel-9-for-x86_64-supplementary-cims-rpms- Supplementary packages
-
jfrog-epel.repo - EPEL packages via JFrog SaaS
- RHEL 9 EPEL packages from centraluhg.jfrog.io
-
jfrog-microsoft.repo - Microsoft packages via JFrog SaaS
- Microsoft Defender ATP and other Microsoft tooling
Credential Management
JFrog authentication uses AWX credential injection with root-only storage and DNF variables:
-
AWX Credential (source of truth):
- AWX Credential: "JFrog SaaS Credential (svc_eoa_jfrog)"
- Injects
jfrog_userandjfrog_tokenas Ansible extra vars at runtime - No Vault retrieval needed - credentials managed directly in AWX
-
DNF variables (runtime access for package management):
- Location:
/etc/dnf/vars/ - Files:
jfrog_userandjfrog_token - Permissions:
0600(root:root only) - Populated from AWX credential at deployment time
- Referenced in repository
baseurlentries as$jfrog_userand$jfrog_token
- Location:
Security considerations
-
Credential storage:
- Credentials injected by AWX "JFrog SaaS Credential (svc_eoa_jfrog)" at deployment time
- Written to
/etc/dnf/vars/jfrog_userand/etc/dnf/vars/jfrog_tokenwith0600permissions (root-only access)
-
Repository access:
- HTTPS-only connections
- Credentials referenced in repository URLs via DNF variable expansion (no direct environment variables required)
- No plaintext credentials in repository
.repofiles; only$jfrog_userand$jfrog_tokenplaceholders
-
Access control:
- Only root can read the DNF variable files (
/etc/dnf/vars/jfrog_*) - Non-privileged users cannot access JFrog tokens
- Token rotation managed via AWX credential updates that refresh DNF variable files
- Only root can read the DNF variable files (
Prerequisites
- RHEL 9 server (RHEL 8 not supported)
- Network access to:
centraluhg.jfrog.io(JFrog SaaS)rhelpatch.cloud.uhginfra.com(Red Hat Satellite)
- AWX access with JFrog SaaS credential configured
- Root or sudo privileges
Configuration Steps
Automated Configuration (Recommended)
Use the AWX job template for automated deployment:
-
Navigate to AWX:
https://eoa-awx.optum.com -
Select Job Template: Repository fix for linux
-
Configure the job launch:
- Inventory: Select target inventory or use dynamic inventory
- Limit: Specify target hosts (hostname pattern or group)
- Credentials: Automatically includes:
- epicans1 (SSH access)
- JFrog SaaS Credential (svc_eoa_jfrog)
- Verbosity: Set to 1 (Normal) for standard output
-
Launch the job
-
Monitor execution:
- Watch for successful credential validation
- Verify repository file creation
- Check post-deployment repository list
-
Validation:
- Review job output for any errors
- Verify all repositories are accessible
- Confirm package availability
Manual Configuration (Emergency Only)
For manual configuration when AWX is unavailable:
WARNING: Manual configuration bypasses automation safeguards and should only be used in emergencies.
# 1. Backup existing configuration
cp /etc/yum.repos.d/uhc.repo /etc/yum.repos.d/uhc.repo.backup.$(date +%Y%m%d%H%M%S)
# 2. Create satellite.repo
cat > /etc/yum.repos.d/satellite.repo <<'EOF'
[rhel-9-for-x86_64-baseos-cims-rpms]
name=Red Hat Enterprise Linux 9 for x86_64 - BaseOS from CIMS (RPMs)
baseurl=https://rhelpatch.cloud.uhginfra.com/repos/30/rhel-9-for-x86_64-baseos-rpms
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
enabled=1
[rhel-9-for-x86_64-appstream-cims-rpms]
name=Red Hat Enterprise Linux 9 for x86_64 - AppStream from CIMS (RPMs)
baseurl=https://rhelpatch.cloud.uhginfra.com/repos/30/rhel-9-for-x86_64-appstream-rpms
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
enabled=1
[rhel-9-for-x86_64-supplementary-cims-rpms]
name=Red Hat Enterprise Linux 9 for x86_64 - Supplementary from CIMS (RPMs)
baseurl=https://rhelpatch.cloud.uhginfra.com/repos/30/rhel-9-for-x86_64-supplementary-rpms
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
enabled=1
EOF
# 3. Create DNF variables for credentials (URL-encoded)
mkdir -p /etc/dnf/vars
# Note: Username must be URL-encoded if it contains @ or other special characters
echo "svc_eoa_jfrog%40uhg.com" > /etc/dnf/vars/jfrog_user
echo "YOUR_TOKEN_HERE" > /etc/dnf/vars/jfrog_token
chmod 600 /etc/dnf/vars/jfrog_*
# 4. Create jfrog-epel.repo
cat > /etc/yum.repos.d/jfrog-epel.repo <<'EOF'
[jfrog-epel]
name=RHEL 9 EPEL
baseurl=https://$jfrog_user:$jfrog_token@centraluhg.jfrog.io/artifactory/glb-rpm-epel-rem/9/Everything/x86_64/
gpgcheck=1
gpgkey=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
repo_gpgcheck=1
enabled=1
EOF
# 5. Create jfrog-microsoft.repo
cat > /etc/yum.repos.d/jfrog-microsoft.repo <<'EOF'
[packages-microsoft-com-prod]
name=Microsoft Production
baseurl=https://$jfrog_user:$jfrog_token@centraluhg.jfrog.io/artifactory/glb-rpm-rhel9-microsoft-rem
gpgcheck=0
enabled=1
EOF
# 6. Rename old configuration (use current date: YYYYMMDD)
mv /etc/yum.repos.d/uhc.repo /etc/yum.repos.d/uhc.repo.$(date +%Y%m%d)
# 7. Clean cache and test
dnf clean all
dnf repolist
Validation
After configuration, verify the setup:
# 1. Check repository files exist
ls -la /etc/yum.repos.d/{satellite,jfrog-*}.repo
# 2. Verify DNF credential variables exist
ls -la /etc/dnf/vars/jfrog_*
# 3. List active repositories
dnf repolist
# 4. Test repository access
dnf list available --repo=jfrog-epel | head -20
dnf list available --repo=packages-microsoft-com-prod | head -20
# 5. Test package installation from EPEL
dnf info psmimic # Should show package from EPEL
# 6. Verify package availability
dnf search mdatp # Microsoft Defender (should be available)
Expected Results
- Repository files: 3 files present (satellite.repo, jfrog-epel.repo, jfrog-microsoft.repo)
- DNF credential variables: 2 files in /etc/dnf/vars/ with 0600 permissions (jfrog_user, jfrog_token)
- Active repositories: 5-6 repositories enabled (3 satellite + 2 jfrog + any other)
- Repository access: No errors when accessing repositories
- Package availability: Packages available from all repositories
Troubleshooting
Repository Access Fails
Symptom: dnf repolist shows errors for JFrog repositories
Possible Causes:
- DNF credential variables missing or incorrect permissions
- Network connectivity issues
- Token expired or invalid
- Incorrect credential values
Resolution:
# Check DNF credential variables
ls -la /etc/dnf/vars/jfrog_*
# Should show 0600 permissions
# Verify variables are readable
cat /etc/dnf/vars/jfrog_user
# Should display: svc_eoa_jfrog%40uhg.com (URL-encoded)
# Test network connectivity
curl -I https://centraluhg.jfrog.io
# Should return 200 or 401 (not connection error)
# Check DNF logs
tail -50 /var/log/dnf.log
# Look for authentication or network errors
# Verify token is valid (contact Platform Team if expired)
DNF Variable Permissions
Symptom: "Permission denied" errors when accessing repositories
Resolution:
# Fix ownership
chown root:root /etc/dnf/vars/jfrog_*
# Fix permissions
chmod 600 /etc/dnf/vars/jfrog_*
# Verify
ls -la /etc/dnf/vars/jfrog_*
DNF Variables Not Set
Symptom: Repository access fails or dnf shows authentication errors
Resolution:
# Check if DNF variables exist
ls -la /etc/dnf/vars/jfrog_*
# Verify username is URL-encoded
cat /etc/dnf/vars/jfrog_user
# Should show: svc_eoa_jfrog%40uhg.com
# If missing, recreate manually or re-run AWX playbook
Migration from uhc.repo
Symptom: Packages not found after migration
Resolution:
# 1. Check which repository provided the package previously
dnf provides <package_name>
# 2. Verify equivalent repository exists in new configuration
dnf repolist
# 3. If package was from uhc.repo's Everything section:
# It should now be available from jfrog-epel
# 4. Update package source if needed or restore backup
mv /etc/yum.repos.d/uhc.repo.backup.* /etc/yum.repos.d/uhc.repo
Repository Metadata Issues
Symptom: DNF complains about repository metadata
Resolution:
# Clean all DNF metadata
dnf clean all
dnf makecache
# If still failing, check repository URLs
dnf repoinfo jfrog-epel
dnf repoinfo packages-microsoft-com-prod
Rollback Procedure
If issues occur post-deployment, rollback to previous configuration:
# 1. Stop any DNF operations
killall dnf # Use with caution
# 2. Remove new repository files
rm /etc/yum.repos.d/satellite.repo
rm /etc/yum.repos.d/jfrog-epel.repo
rm /etc/yum.repos.d/jfrog-microsoft.repo
# 3. Restore from timestamped file (find most recent)
ls -lt /etc/yum.repos.d/uhc.repo.* | head -1
# Then restore (replace YYYYMMDD with actual timestamp)
mv /etc/yum.repos.d/uhc.repo.YYYYMMDD /etc/yum.repos.d/uhc.repo
# 4. Or restore from backup
cp /etc/yum.repos.d/uhc.repo.backup.YYYYMMDDHHMMSS /etc/yum.repos.d/uhc.repo
# 5. Clean cache
dnf clean all
# 6. Verify
dnf repolist
# 7. Test package access
dnf list available | head
Note:
- The DNF credential variable files (
/etc/dnf/vars/jfrog_*) can remain in place—they won't cause issues if the JFrog repository files are removed. - The renamed uhc.repo file uses a timestamp suffix (e.g., uhc.repo.20260317) to prevent accidental overwriting of existing backups.
Related Documentation
- Ansible Role: ohemr-ansible-role-base-os-config
- AWX Job Templates
- Linux Server Standards
- Repository Architecture
- AWX Credentials Management
Support
- AWX Issues: Open issue in
ohemr-issue-trackerrepository - JFrog Access: Contact Platform Team via Teams channel
- Credential Issues: AWX administrators or Platform Team
- Emergency Support: Epic Azure oncall
Changelog
| Date | Version | Changes |
|---|---|---|
| 2026-03-16 | 1.0.0 | Initial documentation for JFrog repository configuration |