Publishing Ansible Roles to Galaxy

    Table of Contents

    1. Prerequisites
    2. Workflow Overview
    3. Git and SSH Setup
    4. GitHub Repository Creation
    5. Ansible Galaxy Token Configuration
    6. GitHub Actions Automation
    7. Ansible Development Tools
    8. Role Testing with Molecule
    9. Publishing Process
    10. Troubleshooting

    Prerequisites

    Before starting, ensure you have the following:

    • Operating System: Linux/macOS/WSL on Windows
    • Python: Version 3.8 or higher
    • Git: Latest version installed
    • GitHub Account: For repository hosting
    • Ansible Galaxy Account: For role publishing
    • Docker: For testing with Molecule (optional but recommended)

    Required Tools Installation

    # Ubuntu/Debian
    sudo apt update
    sudo apt install git python3 python3-pip
    
    # CentOS/RHEL/Fedora
    sudo yum install git python3 python3-pip
    # or
    sudo dnf install git python3 python3-pip
    Bash

    Workflow Overview

    graph TD
        A[Start: Create Ansible Role] --> B[Git Repository Setup]
        B --> C[SSH Key Configuration]
        C --> D[GitHub Repository Creation]
        D --> E[Local Repository Initialization]
        E --> F[Ansible Galaxy Token Setup]
        F --> G[GitHub Secrets Configuration]
        G --> H[GitHub Actions Workflow]
        H --> I[Development Tools Setup]
        I --> J[Molecule Testing Setup]
        J --> K[Role Development]
        K --> L[Quality Checks]
        L --> M{Tests Pass?}
        M -->|No| K
        M -->|Yes| N[Create Release Tag]
        N --> O[GitHub Actions Triggers]
        O --> P[Automatic Galaxy Publishing]
        P --> Q[Role Available on Galaxy]
    
        style A fill:#e1f5fe
        style Q fill:#c8e6c9
        style M fill:#fff3e0

    Git and SSH Setup

    Step 1: Git Configuration

    # Install Git (if not already installed)
    sudo apt install git
    
    # Create project directory
    mkdir ansible-role-apache
    cd ansible-role-apache/
    
    # Configure Git globally (replace with your information)
    git config --global user.name "Ankush More"
    git config --global user.email "ankush.more.email@gmail.com"
    git config --global init.defaultBranch main
    git config --global core.autocrlf input
    Bash

    Note: The core.autocrlf setting helps handle line ending differences between operating systems.

    Step 2: SSH Key Generation and Configuration

    SSH keys provide secure authentication to GitHub without requiring passwords.

    # Generate ED25519 SSH key (more secure than RSA)
    ssh-keygen -t ed25519 -C "ankush.more.email@gmail.com"
    
    # Start SSH agent
    eval "$(ssh-agent -s)"
    
    # Add SSH key to agent
    ssh-add ~/.ssh/id_ed25519
    
    # Display public key for copying to GitHub
    cat ~/.ssh/id_ed25519.pub
    Bash

    Expected Output:

    Generating public/private ed25519 key pair.
    Enter file in which to save the key (/home/terradmin/.ssh/id_ed25519): 
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/terradmin/.ssh/id_ed25519
    Your public key has been saved in /home/terradmin/.ssh/id_ed25519.pub
    The key fingerprint is:
    SHA256:8xoNlczGRkvyqrNhriURgtH8k33O37653j0Rd1OEwdM ankush.more.email@gmail.com
    The key's randomart image is:
    +--[ED25519 256]--+
    |.o      . o  ..=.|
    | oo      O o  + E|
    |. ...o    @    ..|
    |   .+.. .=     oo|
    |    .. +S       =|
    |     . .o=     . |
    |    . * ..o.    .|
    |     = + o. .o o |
    |    ..o .  o*o. o|
    +----[SHA256]-----+
    Agent pid 1153
    Identity added: /home/terradmin/.ssh/id_ed25519 (ankush.more.email@gmail.com)
    ssh-ed25519 AAAAC3Nza<...KEY...> ankush.more.email@gmail.com
    Initialized empty Git repository in /home/terradmin/ansible-role-apache/.git/
    Bash

    Step 3: Add SSH Key to GitHub

    1. Copy the SSH public key from the previous step
    2. Go to GitHub → Settings → SSH and GPG keys
    3. Click “New SSH key”
    4. Paste your public key and give it a descriptive title
    5. Click “Add SSH key”

    Step 4: Test SSH Connection

    # Test SSH connection to GitHub
    ssh -T git@github.com
    Bash

    You should see a message like: “Hi username! You’ve successfully authenticated, but GitHub does not provide shell access.”

    GitHub Repository Creation

    sequenceDiagram
        participant User
        participant GitHub
        participant Local
    
        User->>GitHub: Create new repository
        Note over GitHub: Repository created with README
        User->>Local: Clone repository
        GitHub->>Local: Repository files downloaded
        User->>Local: Add Ansible role files
        User->>Local: Commit changes
        User->>GitHub: Push changes
    1. Create Repository on GitHub:
      • Go to GitHub
      • Click “New repository”
      • Name: ansible-role-apache (or your role name)
      • Description: Brief description of your role
      • Choose Public (required for Galaxy)
      • Initialize with README
      • Add .gitignore (Python template)
      • Choose a license (MIT, Apache 2.0, etc.)
    2. Clone Repository Locally:
    # Clone the repository
    git clone git@github.com:yourusername/ansible-role-apache.git
    cd ansible-role-apache
    Bash

    Method 2: Initialize Local Repository First

    # Initialize local repository
    git init
    git add .
    git commit -m "Initial commit"
    
    # Create repository on GitHub first, then:
    # Add remote origin
    git remote add origin git@github.com:yourusername/ansible-role-apache.git
    
    # Push to GitHub
    git branch -M main
    git push -u origin main
    Bash

    Ansible Galaxy Token Configuration

    Step 1: Generate Galaxy API Token

    1. Login to Ansible Galaxy:
    2. Generate API Token:
      • Navigate to Token Management
      • Click “Create Token”
      • Provide a descriptive name (e.g., “GitHub Actions CI/CD”)
      • Copy the generated token immediately (it won’t be shown again)

    Step 2: Configure GitHub Repository Secrets

    GitHub Secrets allow secure storage of sensitive information like API tokens.

    graph TD
        A[Galaxy Token Generated] --> B[GitHub Repository]
        B --> C[Settings Tab]
        C --> D[Secrets and Variables]
        D --> E[Actions Tab]
        E --> F[New Repository Secret]
        F --> G[Add GALAXY_API_KEY]
        G --> H[Token Stored Securely]
    
        style A fill:#fff3e0
        style H fill:#c8e6c9

    Steps to add the secret:

    1. Go to your GitHub repository
    2. Click Settings tab
    3. Navigate to Secrets and variablesActions
    4. Click New repository secret
    5. Name: GALAXY_API_KEY
    6. Value: Paste your Galaxy API token
    7. Click Add secret

    Step 3: GitHub Actions Token

    GitHub automatically provides a GITHUB_TOKEN for Actions workflows with the following permissions:

    • Read repository contents
    • Write to repository (for releases)
    • Read/write packages

    For more information, see: Automatic token authentication

    Ansible Development Tools

    Installing Required Tools

    # Configure pip to allow system packages (if needed)
    python3 -m pip config set global.break-system-packages true
    
    # Install Ansible and quality tools
    pip install ansible ansible-lint molecule molecule-docker pytest-testinfra yamllint
    
    # Add local bin to PATH (add to ~/.bashrc for persistence)
    export PATH="~/.local/bin:$PATH"
    Bash

    Tool Descriptions

    ToolPurposeConfiguration
    ansibleCore Ansible automation engineansible.cfg
    ansible-lintLinting and best practices checker.ansible-lint
    moleculeTesting framework for Ansible rolesmolecule/ directory
    molecule-dockerDocker driver for MoleculeIncluded with molecule
    pytest-testinfraInfrastructure testingmolecule/default/tests/
    yamllintYAML syntax and style checker.yamllint

    Role Testing with Molecule

    Initialize Molecule Testing

    # Initialize molecule scenario with Docker driver
    molecule init scenario -d docker
    Bash

    This creates the following structure:

    molecule/
    └── default/
        ├── molecule.yml          # Molecule configuration
        ├── converge.yml         # Playbook to test
        ├── verify.yml           # Additional verification tasks
        └── tests/
            └── test_default.py  # Python tests with testinfra
    Bash

    Molecule Configuration Example

    Create molecule/default/molecule.yml:

    ---
    dependency:
      name: galaxy
    driver:
      name: docker
    platforms:
      - name: instance
        image: quay.io/ansible/molecule-docker-runner-centos7
        pre_build_image: true
    provisioner:
      name: ansible
    verifier:
      name: ansible
    scenario:
      test_sequence:
        - dependency
        - lint
        - cleanup
        - destroy
        - syntax
        - create
        - prepare
        - converge
        - idempotence
        - side_effect
        - verify
        - cleanup
        - destroy
    YAML

    Running Tests

    # Run full test suite
    molecule test
    
    # Run specific test phases
    molecule lint          # Lint the role
    molecule converge      # Run the role
    molecule verify        # Run verification tests
    molecule destroy       # Clean up test environment
    Bash

    GitHub Actions Automation

    Creating the Workflow File

    Create .github/workflows/release.yml:

    ---
    name: Release to Galaxy
    
    on:
      push:
        tags:
          - 'v*'  # Triggers on version tags like v1.0.0
    
    jobs:
      release:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Set up Python
            uses: actions/setup-python@v4
            with:
              python-version: '3.9'
    
          - name: Install dependencies
            run: |
              python -m pip install --upgrade pip
              pip install ansible ansible-lint yamllint
    
          - name: Lint Ansible role
            run: |
              ansible-lint .
              yamllint .
    
          - name: Create Galaxy release
            run: |
              ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} \
                                         $(echo ${{ github.repository }} | cut -d/ -f1) \
                                         $(echo ${{ github.repository }} | cut -d/ -f2)
    YAML

    Advanced Workflow with Testing

    ---
    name: CI/CD Pipeline
    
    on:
      push:
        branches: [ main, develop ]
      pull_request:
        branches: [ main ]
      release:
        types: [ published ]
    
    jobs:
      test:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            python-version: [3.8, 3.9, '3.10']
    
        steps:
          - uses: actions/checkout@v4
    
          - name: Set up Python ${{ matrix.python-version }}
            uses: actions/setup-python@v4
            with:
              python-version: ${{ matrix.python-version }}
    
          - name: Install dependencies
            run: |
              python -m pip install --upgrade pip
              pip install ansible ansible-lint molecule molecule-docker pytest-testinfra yamllint
    
          - name: Lint with ansible-lint
            run: ansible-lint .
    
          - name: Test with molecule
            run: molecule test
    
      release:
        needs: test
        runs-on: ubuntu-latest
        if: github.event_name == 'release'
    
        steps:
          - uses: actions/checkout@v4
    
          - name: Release to Galaxy
            run: |
              ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} \
                                         ${{ github.repository_owner }} \
                                         ${{ github.event.repository.name }}
    YAML

    Publishing Process

    Step 1: Prepare Release

    # Ensure all changes are committed
    git add .
    git commit -m "Prepare release v1.0.0"
    
    # Create and push tag
    git tag -a v1.0.0 -m "First release v1.0.0"
    git push origin main --tags
    Bash

    Release Process Flow

    graph TD
        A[Code Changes] --> B[Commit Changes]
        B --> C[Create Git Tag]
        C --> D[Push to GitHub]
        D --> E[GitHub Actions Triggered]
        E --> F[Run Tests]
        F --> G{Tests Pass?}
        G -->|No| H[Fix Issues]
        H --> A
        G -->|Yes| I[Lint Code]
        I --> J{Lint Pass?}
        J -->|No| H
        J -->|Yes| K[Import to Galaxy]
        K --> L[Role Published]
        L --> M[Available on Galaxy]
    
        style A fill:#e1f5fe
        style M fill:#c8e6c9
        style G fill:#fff3e0
        style J fill:#fff3e0

    Step 2: Verify Publication

    1. Check GitHub Actions workflow completion
    2. Visit Ansible Galaxy
    3. Search for your role: namespace.role_name
    4. Verify role information and documentation

    Troubleshooting

    Common Issues and Solutions

    1. SSH Authentication Failed

    # Problem: Permission denied (publickey)
    # Solution: Check SSH key configuration
    ssh-add -l  # List loaded keys
    ssh -T git@github.com  # Test connection
    Bash

    2. Galaxy Import Failed

    • Issue: Repository not public
      • Solution: Make repository public in GitHub settings
    • Issue: Invalid role structure

    3. GitHub Actions Workflow Failed

    # Check workflow logs in GitHub Actions tab
    # Common fixes:
    env:
      ANSIBLE_FORCE_COLOR: '1'
      PY_COLORS: '1'
    YAML

    4. Molecule Test Failures

    # Debug molecule issues
    molecule --debug test
    molecule login  # Interactive debugging
    Bash

    5. Linting Errors

    # Fix common ansible-lint issues
    ansible-lint --fix .
    
    # Check yamllint configuration
    yamllint --config-file .yamllint .
    Bash

    Role Structure Requirements

    Your role must follow this structure for Galaxy compatibility:

    ansible-role-name/
    ├── README.md
    ├── meta/
       └── main.yml          # Role metadata (required)
    ├── tasks/
       └── main.yml          # Main tasks
    ├── handlers/
       └── main.yml          # Handlers
    ├── templates/
    ├── files/
    ├── vars/
       └── main.yml          # Variables
    ├── defaults/
       └── main.yml          # Default variables
    ├── tests/
       ├── inventory
       └── test.yml
    └── .github/
        └── workflows/
            └── release.yml   # CI/CD workflow
    Bash

    Best Practices

    1. Version Tagging: Use semantic versioning (v1.0.0, v1.1.0, v2.0.0)
    2. Documentation: Maintain comprehensive README.md
    3. Testing: Always test roles with Molecule before release
    4. Security: Never commit sensitive data; use variables and secrets
    5. Compatibility: Test across multiple OS distributions
    6. Idempotency: Ensure roles can run multiple times safely

    Note: Replace yourusername and ansible-role-apache with your actual GitHub username and role name throughout this guide.


    Discover more from Altgr Blog

    Subscribe to get the latest posts sent to your email.

    Leave a Reply

    Your email address will not be published. Required fields are marked *