17. Multitier Architecture

Multitier Architeture e.g web & db

17.1. Manage Host Groups

  • a good solution is to create a parent-group for an application
  • the tiers are children of the application group
# 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

17.2. 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)

17.3. Mixing multitier and multienv

  • create the inventory host groups for production and testing
# file: production
[flask_web]
web1.pascal.lab

[flask_db]
db.pascal.lab

[flask_app:children]
flask_web
flask_db

[production:children]
flask_app
# 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
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
# file: group_vars/all.yml
---
allvar: my first variable for all servers
  • variables for the app (web & db)
# 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
# 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
# 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
# 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)
# 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']"
}
# 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)

17.4. Setup the playbooks

  • create a playbook for the web tier flask_web
# file: play-flask_web.yml
---
- hosts: flask_web
  roles:
    - web_part
  • create a playbook for the db tier flask_db
# file: play-flask_db.yml
---
- hosts: flask_db
  roles:
    - db_part
  • create a “master” playbook and import the web and db playbooks
# file: site.yml
---
- import_playbooks: play-flask_web.yml
- import_playbooks: play-flask_db.yml