Multitier Architecture """""""""""""""""""""" Multitier Architeture e.g ``web`` & ``db`` Manage Host Groups ------------------ * a good solution is to create a parent-group for an application * the tiers are ``children`` of the application group .. code-block:: yaml # file: hosts [flask_web] web1.pascal.lab [flask_db] db.pascal.lab [flask_app:children] flask_web flask_db Now we've got these groups: * flask_web * flask_db * flask_app Setting variables for tiers --------------------------- * variables for both tiers should be placed in the ``flask_app`` group vars e.g (flask_app_db_port) * variables for the ``web`` tier comes into the ``flask_web`` group vars e.g (dns_servers for dmz) * variables for the ``db`` tier comes into the ``flask_db`` group vars e.g (dns_servers for internal zones) Mixing multitier and multienv ----------------------------- * create the inventory host groups for production and testing .. code-block:: yaml # file: production [flask_web] web1.pascal.lab [flask_db] db.pascal.lab [flask_app:children] flask_web flask_db [production:children] flask_app .. code-block:: yaml # file: test [flask_web] web2.pascal.lab [flask_db] db.pascal.lab [flask_app:children] flask_web flask_db [test:children] flask_app Now we've got these groups for our variables: * flask_web * flask_db * flask_app * test * production * specify variables for different tiers and environments .. code-block:: bash group_vars/ ├── all.yml <- variables for all hosts ├── flask_app.yml <- variables for flask_app hosts -> flask_db & flask_web └── flask_web.yml <- variables only for flask_web hosts ├── flask_db.yml <- variables only for flask_db hosts ├── production.yml <- variables for production environment ├── test.yml <- variables for test environment * variables for all servers .. code-block:: yaml # file: group_vars/all.yml --- allvar: my first variable for all servers * variables for the app (web & db) .. code-block:: yaml # file: group_vars/flask_app.yml --- flask_app_db_port: 3306 flask_app_db_address: '0.0.0.0' flask_app_web_port: 8080 * variables for the tiers .. code-block:: yaml # file: group_vars/flask_db.yml --- ntp_servers: - ntp1.internal.lab - ntp2.internal.lab - ntp3.internal.lab # file: group_vars/flask_web.yml --- ntp_servers: - ntp1.dmz.lab - ntp2.dmz.lab - ntp3.dmz.lab * variables for the environments .. code-block:: yaml # file: group_vars/production.yml --- flask_app_db_password: myProdPW flask_app_version: v1.0 # file: group_vars/test.yml --- flask_app_db_password: testPW flask_app_version: v1.1 * create a playbook to print out the variables .. code-block:: yaml # file: play-mixed.yml --- - hosts: all gather_facts: false tasks: - debug: msg: 'App_DB_Port={{ flask_app_db_port }} - App_Version={{ flask_app_version }} - DB_PW={{ flask_app_db_password }} - DB_Bind_Address={{ flask_app_db_address | default("not set") }} - Web_Port={{ flask_app_web_port | default("not set") }} - NTP_Servers={{ ntp_servers }}' * run the playbook for both environments (test and prod) .. code-block:: bash # on prod ansible-playbook -i prod play-mixed.yml TASK [debug] ******************************************************************* ok: [web1.test.lab] => { "msg": "App_DB_Port=3306 - App_Version=v1.0 - DB_PW=myProdPW - DB_Bind_Address=0.0.0.0 - Web_Port=8080 - NTP_Servers=[u'ntp1.dmz.lab', u'ntp2.dmz.lab', u'ntp3.dmz.lab']" } ok: [db.test.lab] => { "msg": "App_DB_Port=3306 - App_Version=v1.0 - DB_PW=myProdPW - DB_Bind_Address=0.0.0.0 - Web_Port=8080 - NTP_Servers=[u'ntp1.internal.lab', u'ntp2.internal.lab', u'ntp3.internal.lab']" } .. code-block:: bash # on test ansible-playbook -i test play-mixed.yml TASK [debug] ******************************************************************* ok: [web2.test.lab] => { "msg": "App_DB_Port=3306 - App_Version=v1.1 - DB_PW=testPW - DB_Bind_Address=0.0.0.0 - Web_Port=8080 - NTP_Servers=[u'ntp1.dmz.lab', u'ntp2.dmz.lab', u'ntp3.dmz.lab']" } ok: [db.test.lab] => { "msg": "App_DB_Port=3306 - App_Version=v1.1 - DB_PW=testPW - DB_Bind_Address=0.0.0.0 - Web_Port=8080 - NTP_Servers=[u'ntp1.internal.lab', u'ntp2.internal.lab', u'ntp3.internal.lab']" } .. important:: This is just a structure example to show how you can define different variable values for tiers and environments. Try to use only a few group_vars files and combine them (like ``flask_app``) Setup the playbooks ------------------- * create a playbook for the web tier ``flask_web`` .. code-block:: yaml # file: play-flask_web.yml --- - hosts: flask_web roles: - web_part * create a playbook for the db tier ``flask_db`` .. code-block:: yaml # file: play-flask_db.yml --- - hosts: flask_db roles: - db_part * create a "master" playbook and import the ``web`` and ``db`` playbooks .. code-block:: yaml # file: site.yml --- - import_playbooks: play-flask_web.yml - import_playbooks: play-flask_db.yml Links ----- * https://www.digitalocean.com/community/tutorials/how-to-manage-multistage-environments-with-ansible