Action: Play Ansible Playbook
GitHub Action for running Ansible Playbooks with comprehensive configuration options for Galaxy, SSH, Vault, privilege escalation, and more.
Features
- Ansible Playbook Execution: Run one or more Ansible playbooks in GitHub Actions workflows
- Galaxy Integration: Auto-detect and install roles and collections from Ansible Galaxy
- SSH Authentication: SSH-agent based key handling with support for multiple keys, passphrases, and bastion hosts
- Vault Support: Secure handling of Ansible Vault passwords via temporary files
- Host Key Verification: Configure known hosts for secure SSH connections
- Dry Run Mode: Preview changes with
--check --diff without applying them
- Retry Mechanism: Automatically retry failed playbook executions
- ansible-lint Integration: Optional pre-execution linting
- Flexible Configuration: 50+ action inputs covering virtually all Ansible CLI options
- Action Outputs: Capture execution status and exit codes for conditional workflow steps
- Step Summary: Automatic GitHub Step Summary with execution results
Quick Start
- name: Deploy with Ansible
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: playbook.yml
inventory: inventory.yml
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
Inputs
Required Inputs
| Input |
Description |
playbook |
One or more playbooks to apply. Supports comma-separated (play1.yml,play2.yml) or multiline YAML syntax. |
inventory |
One or more inventory host files. Supports comma-separated or multiline YAML syntax. |
Execution Control
| Input |
Default |
Description |
execution_timeout |
30 |
Timeout in minutes for playbook execution. |
retries |
0 |
Number of times to retry on failure (0 = no retries). |
retry_delay |
30 |
Delay in seconds between retries. |
forks |
5 |
Number of parallel processes to use. |
check |
|
Perform a dry run without making changes. |
diff |
|
Show differences in files and templates when changing them. |
dry_run |
false |
Enables both check and diff for a convenient dry-run mode. |
flush_cache |
|
Clear the fact cache for every host. |
force_handlers |
|
Run all handlers even if a task fails. |
lint |
false |
Run ansible-lint on playbooks before execution. |
Playbook Selection
| Input |
Description |
limit |
Limit execution to a specific group of hosts. |
tags |
Run only tasks and plays with the specified tags. |
skip_tags |
Skip plays and tasks matching these tags. |
start_at_task |
Start execution at the task matching this name. |
extra_vars |
Additional variables in key=value format. Supports multiline YAML. |
module_path |
Prepend directories to the module library path. Supports multiline YAML. |
List Operations (no execution)
| Input |
Description |
list_hosts |
Output a list of matching hosts. |
list_tags |
List all available tags. |
list_tasks |
List all tasks that would be executed. |
syntax_check |
Perform a syntax check without executing. |
Ansible Galaxy
| Input |
Description |
galaxy_file |
Path to the Galaxy requirements file. Auto-detects requirements.yml / requirements.yaml if omitted. |
galaxy_force |
Force reinstallation of roles or collections. |
galaxy_api_key |
API key for authenticating with Ansible Galaxy. |
galaxy_api_server_url |
URL of the Ansible Galaxy API server. |
galaxy_collections_path |
Path where Galaxy collections are stored. |
galaxy_disable_gpg_verify |
Disable GPG signature verification. |
galaxy_force_with_deps |
Force installation of collections with dependencies. |
galaxy_ignore_certs |
Ignore SSL certificate validation. |
galaxy_ignore_signature_status_codes |
HTTP status codes to ignore during signature validation. |
galaxy_keyring |
Path to the GPG keyring. |
galaxy_offline |
Enable offline mode. |
galaxy_pre |
Allow pre-release versions. |
galaxy_required_valid_signature_count |
Required valid GPG signatures. |
galaxy_requirements_file |
Alternative path to requirements file. |
galaxy_signature |
Specific GPG signature to verify. |
galaxy_timeout |
Timeout in seconds for Galaxy operations. |
galaxy_upgrade |
Automatically upgrade collections. |
galaxy_no_deps |
Disable automatic dependency resolution. |
SSH Authentication
| Input |
Description |
private_key |
SSH private key content. Loaded into ssh-agent for ProxyCommand/bastion support. Store in a GitHub Secret. |
private_key_passphrase |
Passphrase for the SSH private key. Store in a GitHub Secret. |
additional_private_keys |
Additional SSH keys to load into ssh-agent. Supports multiline YAML. Requires private_key. |
known_hosts |
SSH known hosts entries for host key verification. Supports multiline YAML. |
user |
Username for connections. |
connection |
Connection type (e.g., ssh, local). |
timeout |
Connection timeout in seconds. |
ssh_common_args |
Common arguments for all SSH-based methods. |
ssh_extra_args |
Extra arguments for SSH only. |
scp_extra_args |
Extra arguments for SCP only. |
sftp_extra_args |
Extra arguments for SFTP only. |
Ansible Vault
| Input |
Description |
vault_id |
Vault identity to use. |
vault_password |
Vault password. Store in a GitHub Secret. |
Privilege Escalation
| Input |
Description |
become |
Enable privilege escalation. |
become_method |
Escalation method (e.g., sudo, su). |
become_user |
User to impersonate. |
Output and Debugging
| Input |
Description |
verbose |
Verbosity level (0-4). |
output_file |
Save Ansible stdout to a file. |
Outputs
| Output |
Description |
status |
Execution status: success or failed. |
exit_code |
Ansible exit code (0=success, 2=host failed, 4=unreachable). |
Examples
Basic Usage
- name: Run Playbook
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
With SSH Key
- name: Deploy
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
user: deploy
With Galaxy Requirements
- name: Deploy
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
galaxy_file: requirements.yml
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
Dry Run
- name: Preview Changes
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
dry_run: true
Multiple Playbooks and Inventories
- name: Deploy All
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: |
site.yml
monitoring.yml
inventory: |
production.yml
staging.yml
tags: deploy
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
With Retry and Timeout
- name: Deploy with Retry
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
retries: 3
retry_delay: 60
execution_timeout: 60
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
Vault-Encrypted Playbook
- name: Deploy
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
vault_password: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
Using Action Outputs
- name: Deploy
id: ansible
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
output_file: ansible-output.log
- name: Notify on Failure
if: steps.ansible.outputs.status == 'failed'
run: |
echo "Deployment failed with exit code ${{ steps.ansible.outputs.exit_code }}"
# Send notification, create issue, etc.
Known Hosts Verification
- name: Deploy
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
known_hosts: |
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
Multiple SSH Keys
- name: Deploy
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
private_key_passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
additional_private_keys: |
${{ secrets.SECONDARY_SSH_KEY }}
${{ secrets.TERTIARY_SSH_KEY }}
With ansible-lint
- name: Lint and Deploy
uses: git.desord.re/public/forgejo/action.playbook@0.5.1
with:
playbook: deploy.yml
inventory: hosts.yml
lint: true
private_key: ${{ secrets.SSH_PRIVATE_KEY }}
SSH Authentication
Storing SSH Keys in GitHub Secrets
- Go to repository Settings → Secrets and variables → Actions
- Click New repository secret
- Name:
SSH_PRIVATE_KEY
- Value: Paste your entire private key (including
-----BEGIN/END----- headers)
- Click Add secret
SSH Key Normalization
SSH private keys are automatically normalized before use:
- Windows line endings (
CRLF) are converted to Unix format (LF)
- Missing trailing newlines are added per RFC 7468
- Keys are validated for proper format
SSH Agent and Bastion Hosts
Private keys are loaded into ssh-agent, making them available to:
ProxyCommand and jump host configurations
- Multi-hop SSH connections
- Any SSH-based tool that respects
SSH_AUTH_SOCK
Passphrase-Protected Keys
If your SSH key has a passphrase, provide it via private_key_passphrase. The action uses SSH_ASKPASS to unlock the key non-interactively.
Security Best Practices
- Never commit secrets: Always use GitHub Secrets for
private_key, private_key_passphrase, and vault_password.
- Use
known_hosts: Enable host key verification instead of disabling ANSIBLE_HOST_KEY_CHECKING.
- Pin to a version: Use
@0.5.1 instead of @master or @main for reproducible builds.
- Limit playbook scope: Use
limit, tags, and check to control execution scope.
- Review diffs: Use
dry_run: true in PR workflows to preview changes.
Development
See CONTRIBUTING.md for development setup, coding standards, and the pull request process.
License
This project is under the MIT License. See the LICENSE file for the full license text.
Copyright
(c) 2020-2026, Arillso