fabrix
fabrix copied to clipboard
Fabrix is legacy Fabric extension for configuration management
Fabrix is legacy python 2.7 project, now it is read only archive.
Possible is python 3.6+ configuration management system: https://github.com/makhomed/possible
Fabrix
Fabrix is Fabric <http://docs.fabfile.org/en/1.14/>_ extension for configuration management.
Fabric <http://docs.fabfile.org/en/1.14/>_ is tool for application deployment and systems administration tasks.
But configuration management with Fabric is not easy, because Fabric
does not provide any useful functions for configuration management.
cuisine <https://github.com/sebastien/cuisine>_ and fabtools <https://github.com/fabtools/fabtools>_
are two well known attempts to make Fabric more comfortable for configiration management,
they are based on ideas of Chef <https://www.chef.io/>_ and Puppet <https://puppet.com/>_.
Ansible <https://www.ansible.com/>_ is well known tool for configuration management.
But Ansible has its own drawbacks. Ansible requires from users learning huge yaml-based programming language.
Already exists more then 1300 Ansible modules <http://docs.ansible.com/ansible/latest/list_of_all_modules.html>_.
You need to spent many time for learning this special Ansible programming language and Ansible modules.
And after all you often still need to write own shell scripts or even write own Ansible modules,
because potential of Ansible yaml-based programming language is very limited.
Fabrix has an approach to create useful and simple Fabric extension for configuration management.
Fabrix is build to integrate all advantages of Fabric and Ansible without any of their drawbacks.
Fabrix allows write easy to understand Ansible-like idempotent fabfiles on pure Python.
Installation
.. code-block:: bash
pip install -U fabrix
Links
Fabrix Documentation <https://fabrix.readthedocs.io/>_Fabrix GitHub Home Page <https://github.com/makhomed/fabrix>_Fabrix Python Package Index <https://pypi.python.org/pypi/Fabrix>_
Examples
Using Jinja2 templates
.. code-block:: python
from fabrix.api import render
def hello():
print render("Hello, {{ name }}!", name="World")
Editing systemd unit files
.. code-block:: python
from fabrix.api import systemctl_edit, systemctl_restart
def example():
changed = systemctl_edit("mysqld.service", """
[Service]
LimitNOFILE = 262144
""")
if changed:
systemctl_restart("mysqld.service")
Editing configuration files
.. code-block:: python
from fabric.api import run
from fabrix.api import edit_file, replace_line, substitute_line, strip_line
def edit_grub():
changed = edit_file("/etc/default/grub",
replace_line(r"GRUB_TIMEOUT=.*", r"GRUB_TIMEOUT=1"),
replace_line(r"(GRUB_CMDLINE_LINUX=.*)\brhgb\b(.*)", r"\1selinux=0\2"),
replace_line(r"(GRUB_CMDLINE_LINUX=.*)\bquiet\b(.*)", r"\1panic=1\2"),
substitute_line(r"\s+", r" "),
strip_line(),
)
if changed:
run("grub2-mkconfig -o /boot/grub2/grub.cfg")
Installing PHP 7.0 from remi repo
.. code-block:: python
from fabrix.api import is_file_not_exists, yum_install
from fabrix.api import edit_file, edit_ini_section, replace_line
def install_php():
if is_file_not_exists("/etc/yum.repos.d/epel.repo"):
yum_install("https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm")
if is_file_not_exists("/etc/yum.repos.d/remi-php70.repo"):
yum_install("https://rpms.remirepo.net/enterprise/remi-release-7.rpm")
edit_file("/etc/yum.repos.d/remi-php70.repo",
edit_ini_section("[remi-php70]",
replace_line("enabled=0", "enabled=1")
)
)
yum_install("""
php-cli
php-common
php-fpm
php-gd
php-mbstring
php-mysql
php-pdo
php-pear
php-pecl-imagick
php-process
php-xml
php-opcache
php-mcrypt
php-soap
""")
Using external configuration
Configuration file ``fabfile.yaml``:
.. code-block:: yaml
roles:
- role: db
hosts:
- db1
- db2
- role: web
hosts:
- web1
- web2
- web3
role_vars:
- role: web
vars:
name: webserver
host_vars:
- host: web1
vars:
name: nginx
defaults:
name: generic
Code ``fabfile.py``:
.. code-block:: python
from fabric.api import env, run, roles, execute
from fabrix.api import conf
@roles("db")
def migrate():
print "Hello, %s!" % conf.name
pass
@roles("web")
def update():
print "Hello, %s!" % conf.name
pass
def deploy():
execute(migrate)
execute(update)
After running ``fab deploy`` we can see:
.. code-block:: bash
$ fab deploy
[db1] Executing task 'migrate'
Hello, generic!
[db2] Executing task 'migrate'
Hello, generic!
[web1] Executing task 'update'
Hello, nginx!
[web2] Executing task 'update'
Hello, webserver!
[web3] Executing task 'update'
Hello, webserver!