asm / php-ansible
A PHP wrapper for Ansible.
Installs: 281 893
Dependents: 1
Suggesters: 0
Security: 0
Stars: 203
Watchers: 14
Forks: 72
Open Issues: 8
Requires
- php: ^8.1.0|^8.2.0|^8.3.0
- psr/log: ^2.0|^3.0
- symfony/process: ^5.3|^6.0|^7.0
Requires (Dev)
- mikey179/vfsstream: ^1.6
- phpstan/phpstan: ^1.12
- phpunit/phpunit: ^10.0|^11.0
README
This library is a OOP-wrapper for the ansible provisioning tool.
I intend to use this library for a symfony2 bundle and also a deployment GUI, based on php/symfony2.
The current implementation is feature-complete for the ansible-playbook
and ansible-galaxy
commands.
Prerequisites
Your OS should be a flavor of linux and ansible has to be installed. It's easiest if ansible is in PATH :-) The library tries to find ansible-playbook and ansible-galaxy by itself or use the paths/executables you provide.
Usage
First instantiate the base object which works as a factory for the commands. Only the first parameter is mandatory, and provides the library with the path to your ansible deployment file structure.
$ansible = new Ansible( '/path/to/ansible/deployment' );
Optionally, you can specify the path of your ansible-playbook
and ansible-galaxy
commands, just in case they are not in the PATH.
$ansible = new Ansible( '/path/to/ansible/deployment', '/optional/path/to/command/ansible-playbook', '/optional/path/to/command/ansible-galaxy' );
You can also pass any PSR compliant logging class to have further details logged. This is especially useful to have the actual run command logged.
$ansible = new Ansible( '/path/to/ansible/deployment' ); // $logger is a PSR-compliant logging implementation (e.g. monolog) $ansible->setLogger($logger);
Playbooks
Then you can use the object just like in your previous ansible deployment.
If you don't specify an inventory file with ->inventoryFile('filename')
, the wrapper tries to determine one, based on your playbook name:
$ansible ->playbook() ->play('mydeployment.yml') // based on deployment root ->user('maschmann') ->extraVars(['project_release' => 20150514092022]) ->limit('test') ->execute();
This will create following ansible command:
$ ansible-playbook mydeployment.yml -i mydeployment --user=maschmann --extra-vars="project-release=20150514092022" --limit=test
For the execute command you can use a callback to get real-time output of the command:
$ansible ->playbook() ->play('mydeployment.yml') // based on deployment root ->user('maschmann') ->extraVars(['project_release' => 20150514092022]) ->limit('test') ->execute(function ($type, $buffer) { if (Process::ERR === $type) { echo 'ERR > '.$buffer; } else { echo 'OUT > '.$buffer; } });
If no callback is given, the method will return the ansible-playbook output as a string, so you can either echo
or directly pipe it into a log/whatever.
You can also pass an external YML/JSON file as extraVars containing a complex data structure to be passed to Ansible:
$ansible ->playbook() ->play('mydeployment.yml') // based on deployment root ->extraVars('/path/to/your/extra/vars/file.yml') ->execute();
You can have a Json output adding json() option that enable 'ANSIBLE_STDOUT_CALLBACK=json' env vars to make a json output in ansible.
$ansible ->playbook() ->json() ->play('mydeployment.yml') // based on deployment root ->extraVars('/path/to/your/extra/vars/file.yml') ->execute();
Galaxy
The syntax follows ansible's syntax with one deviation: list is a reserved keyword in php (array context) and therefore I had to rename it to "modulelist()".
$ansible ->galaxy() ->init('my_role') ->initPath('/tmp/my_path') // or default ansible roles path ->execute();
would generate:
$ ansible-galaxy init my_role --init-path=/tmp/my_path
You can access all galaxy commands:
init()
info()
install()
help()
modulelist()
remove()
You can combine the calls with their possible arguments, though I don't have any logic preventing e.g. --force
from being applied to e.g. info().
Possible arguments/options:
initPath()
offline()
server()
force()
roleFile()
rolesPath()
ignoreErrors()
noDeps()
Process timeout
Default process timeout is set to 300 seconds. If you need more time to execute your processes: Adjust the timeout :-)
$ansible ->galaxy() ->setTimeout(600) …
Development
You can use the provided docker image with make build
which uses a default php-cli docker image and ansible 2.x. See the Dockerfile
for more info.
Start the container with make up
.
Composer install: make vendor
You can run code or the tests within the container: make test c="--testdox"
Thank you for your contributions!
thank you for reviewing, bug reporting, suggestions and PRs :-) xabbuh, emielmolenaar, saverio, soupdiver, linaori, paveldanilin and many others!
Future features
The Next steps for implementation are:
- improve type handling and structure, due to overall complexity of the playbook at the moment
- scalar typehints all over the place
- provide docker support for development
- wrapping the library into a bundle -> maybe
- provide commandline-capabilities -> maybe
License
php-ansible is licensed under the MIT license. See the LICENSE for the full license text.