Uploading Ansible Role to Git Repository

First, create a Git repository for developing an Ansible Role. Then, generate the initial Ansible Role project structure using Ansible Galaxy.

  • Clone the Git repository to your local machine.
1
$ git clone "https://github.com/xxxxx/sample-role.git"
  • Generate Ansible Role initial directory and files.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
$ ansible-galaxy init --force sample-role
- sample-role was created successfully

$ tree sample-role/
sample-role/
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml
  • After developing the Ansible Role, push to Git repository.
1
$ git commit * -m "Add ansible role" && git push

Downloading Ansible Role from Git Repository

Method 1) Download via Ansible Galaxy CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ ansible-galaxy install git+https://github.com/xxxx/sample-role.git,master -p roles/

$ tree roles/
roles/
└── sample-role
    ├── README.md
    ├── defaults
    │   └── main.yml
    ├── handlers
    │   └── main.yml

    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

Method 2) Specify in dependency file and download via CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ vi requirements.yml
- src: git+https://github.com/xxxx/sample-role.git
  version: master

$ ansible-galaxy install -r requirements.yml -p roles/
- extracting sample-role to roles/sample-role
- sample-role was installed successfully

$ tree roles/
roles/
└── sample-role
    ├── README.md
    ├── defaults
    │   └── main.yml
    ├── handlers
    │   └── main.yml

    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

Writing ‘requirements.yml’

  • src
    • username.role_name: Used to download Ansible Roles registered in the official Ansible Galaxy repository.
    • url: Used to download from SCMs supported by Ansible Galaxy.
  • scm
    • Specify the SCM name to integrate. Default is ‘git’ (as of ansible-galaxy 2.2.1.0, only git and hg are supported)
  • version
    • Specify tag name / commit hash / branch name. Default is ‘master’
    • Only used when downloading from SCM.
  • name
    • Specify the name of the downloaded Ansible Role. By default, uses the name registered in Ansible Galaxy or the Git repository name.

See the examples below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# from galaxy
- src: yatesr.timezone

# from GitHub
- src: https://github.com/bennojoy/nginx

# from GitHub, overriding the name and specifying a specific tag
- src: https://github.com/bennojoy/nginx
  version: master
  name: nginx_role

# from a webserver, where the role is packaged in a tar.gz
- src: https://some.webserver.example.com/files/master.tar.gz
  name: http-role

# from Bitbucket
- src: git+http://bitbucket.org/willthames/git-ansible-galaxy
  version: v1.4

# from Bitbucket, alternative syntax and caveats
- src: http://bitbucket.org/willthames/hg-ansible-galaxy
  scm: hg

# from GitLab or other git-based scm
- src: git@gitlab.company.com:mygroup/ansible-base.git
  scm: git
  version: "0.1"  # quoted, so YAML doesn't parse this as a floating-point value

Using Private Git Repositories

SSH Key Based Authentication

1
2
3
4
5
# requirements.yml
- src: git@github.com:myorg/private-role.git
  scm: git
  version: v1.0.0
  name: private_role
1
2
3
4
5
6
# SSH key setup
$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_rsa

# Install roles
$ ansible-galaxy install -r requirements.yml

Personal Access Token (HTTPS)

1
2
3
4
# requirements.yml
- src: https://<token>@github.com/myorg/private-role.git
  version: main
  name: private_role

Deploy Key Setup

You can use GitHub/GitLab’s Deploy Key feature to securely configure read-only access.

1
2
3
4
5
# Generate deploy key
$ ssh-keygen -t ed25519 -C "deploy@myserver" -f deploy_key

# Register public key in Git repository
# Settings > Deploy keys > Add deploy key

CI/CD Pipeline Integration

Jenkins Pipeline Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
pipeline {
    agent any
    
    stages {
        stage('Install Dependencies') {
            steps {
                sh 'ansible-galaxy install -r requirements.yml -p roles/'
            }
        }
        
        stage('Lint') {
            steps {
                sh 'ansible-lint site.yml'
            }
        }
        
        stage('Test') {
            steps {
                sh 'molecule test'
            }
        }
        
        stage('Deploy') {
            steps {
                sh 'ansible-playbook -i inventory/production site.yml'
            }
        }
    }
}

GitHub Actions Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name: Ansible CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'
      
      - name: Install Ansible
        run: pip install ansible ansible-lint
      
      - name: Install Roles
        run: ansible-galaxy install -r requirements.yml -p roles/
      
      - name: Lint Playbook
        run: ansible-lint site.yml
      
      - name: Run Molecule Tests
        run: |
          pip install molecule[docker]
          molecule test

Role Version Management Strategy

Semantic Versioning

MMMPAAIAJJNTOOOCRRRH.:::MIIBBNnaaOcccRokk.mwwPpaaAarrTtddCissHb--lcceoommAppPaaIttiicbbhllaeengfbeeusagtufriexeasdditions
1
2
3
4
# Version ranges not supported in requirements.yml
# Instead, specify exact version
- src: git+https://github.com/xxxx/sample-role.git
  version: v1.2.3  # Exact version

Branch Strategy

maindrheeoovltreeflfbaimoeusxapagestfvtuiv1erx1.re.1)i2.ns.1es0wu-ef-e1a2t3ure

Version Pinning in Production

1
2
3
4
5
6
# Production requirements.yml
- src: git+https://github.com/xxxx/nginx-role.git
  version: v2.1.0  # Pinned with tag

- src: git+https://github.com/xxxx/mysql-role.git
  version: abc123def456  # Pinned with commit hash (safer)

Advanced Role Dependency Management

Nested Dependencies

You can define dependencies on other Roles within a Role.

1
2
3
4
5
6
7
# roles/web-server/meta/main.yml
dependencies:
  - role: common
    vars:
      common_var: value
  - role: nginx
    when: web_server_type == 'nginx'

Conditional Dependencies

1
2
3
4
5
6
# Install dependencies only under certain conditions
dependencies:
  - role: nginx
    when: web_server == 'nginx'
  - role: apache
    when: web_server == 'apache'

Troubleshooting

Common Problems

1. Role Not Found

1
ERROR! the role 'sample-role' was not found

Solution:

1
2
3
4
5
6
7
# Check role paths
$ ansible-galaxy list
# /etc/ansible/roles
# /home/user/.ansible/roles

# Install with specified path
$ ansible-galaxy install -r requirements.yml -p ./roles

2. Version Conflict

1
ERROR! conflicting role requirements

Solution:

1
2
3
4
5
6
7
8
# Use different names when different versions are needed
- src: git+https://github.com/xxxx/nginx-role.git
  version: v1.0.0
  name: nginx_v1

- src: git+https://github.com/xxxx/nginx-role.git
  version: v2.0.0
  name: nginx_v2

3. Git Authentication Failure

1
Permission denied (publickey)

Solution:

1
2
3
4
5
6
# Check SSH key
$ ssh -T git@github.com

# Add key to SSH agent
$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_rsa

4. Installation in Proxy Environment

1
2
3
# Proxy settings
$ export https_proxy=http://proxy.company.com:8080
$ ansible-galaxy install -r requirements.yml

Best Practices

1. Explicit Version Management

1
2
3
4
5
6
7
# Good: Explicit version
- src: git+https://github.com/xxxx/role.git
  version: v1.2.3

# Avoid: Branch name (in production)
- src: git+https://github.com/xxxx/role.git
  version: main  # Branch can change

2. Local Development Environment

1
2
3
4
# ansible.cfg
[defaults]
roles_path = ./roles:~/.ansible/roles
collections_path = ./collections:~/.ansible/collections

3. Role Validation

1
2
3
4
5
# Validate with ansible-lint
$ ansible-lint roles/sample-role/

# Test with molecule
$ molecule test

4. Minimize Dependencies

1
2
# meta/main.yml
dependencies: []  # Avoid unnecessary dependencies

References