2
votes

I am writing a ansible script for my deployment and stuck at one problem. I have 6 tomcat nodes where I have do a rolling deployment i.e. first deploy on 3 nodes and test it. If the test is successful then go for remaining 3 nodes. My current inventory looks like this -

[prod]
prod-1-myapp
prod-2-myapp
prod-3-myapp
prod-4-myapp
prod-5-myapp
prod-6-myapp

[preprod]
preprod-cn-p1

And I am using group_vars where I have prod.yml/preprod.yml to upload the configuration at run time. Is it possible to segregate this host group into 2 and deploy on each of them accordingly. If i create 2 host groups like below, how do i make use of my prod.yml at run time. How will it work?

[prod-1]
prod-1-myapp
prod-2-myapp
prod-3-myapp

[prod-2]
prod-4-myapp
prod-5-myapp
prod-6-myapp

[preprod]
preprod-cn-p1

My Current query -

ansible-playbook myapp-main.yml -e myapp_release_version=5.0.0 -e target_env=prod

myapp-main.yml

---
 - name: Starting with  Myapp Application deployment to tomcat nodes
   hosts: '{{ target_env }}'
   gather_facts: True
   any_errors_fatal: true
   roles:
     - role: deploy
       tags:
         - deploy
       become: yes
       become_user: tomcat
       become_method: sudo

Please if someone can advice. Any help is appreciated

2
You already answered your own question. You can split the inventory, run with -e target_env=prod-1, check if it works and then run the same thing but with -e target_env=prod-2.toydarian
@toydarian I have thought about this but I don't think it will work because I am using group_vars where I have a file name prod.yml which contains all the configurations for production environment. If i use like this -e target_env=prod-1 then how will it pick up those configurations?Shashank Agrawal
Easy, make prod-1 and prod-2 children of a group prod and assign the group vars to the group prod so all hosts in prod-1 and prod-2 will pick them up.toydarian
@toydarian ok will this work? ``` [prod-1] prod-1-myapp prod-2-myapp prod-3-myapp [prod-2] prod-4-myapp prod-5-myapp prod-6-myapp [prod:children] prod-1 prod-2 ```Shashank Agrawal
yes, check out my answer and follow up if it is unclear in some pointtoydarian

2 Answers

2
votes

You basically are almost there.
Split the inventory, run with -e target_env=prod-1, check if it works and then run the same thing but with -e target_env=prod-2.

To share your group variables, your inventory should look like this:

[prod_1]
prod-1-myapp
prod-2-myapp
prod-3-myapp

[prod_2]
prod-4-myapp
prod-5-myapp
prod-6-myapp

[preprod]
preprod-cn-p1

[prod:children]
prod_1
prod_2

All group variables that should be shared on all six prod servers need to be assigned to the group prod.

2
votes

Q: "Deploy on 3 nodes and test it. If the test is successful then go for the remaining 3 nodes." (using group_vars prod.yml / preprod.yml)

A: Make prod_1 and prod_2 the children of prod. For example

shell> cat hosts
[prod_1]
prod-1-myapp
prod-2-myapp
prod-3-myapp

[prod_2]
prod-4-myapp
prod-5-myapp
prod-6-myapp

[prod:children]
prod_1
prod_2

[preprod]
preprod-cn-p1

Then deploy group prod_1. If all is right deploy prod_2. For example, the playbook below

shell> cat playbook.yml
- import_playbook: myapp-main.yml
  vars:
    target_env: prod_1

- hosts: localhost
  gather_facts: false
  tasks:
    - fail:
        msg: Test prod_1 failed
      when: prod_1_failed|default(false)|bool

- import_playbook: myapp-main.yml
  vars:
    target_env: prod_2

shell> cat myapp-main.yml
- hosts: '{{ target_env }}'
  gather_facts: false
  tasks:
    - debug:
        msg: "Deploy {{ inventory_hostname }}"

gives

PLAY [prod_1] ****

TASK [debug] ****
ok: [prod-2-myapp] => {
    "msg": "Deploy prod-2-myapp"
}
ok: [prod-1-myapp] => {
    "msg": "Deploy prod-1-myapp"
}
ok: [prod-3-myapp] => {
    "msg": "Deploy prod-3-myapp"
}

PLAY [localhost] ****

TASK [fail] ****
skipping: [localhost]

PLAY [prod_2] ****

TASK [debug] ****
ok: [prod-4-myapp] => {
    "msg": "Deploy prod-4-myapp"
}
ok: [prod-5-myapp] => {
    "msg": "Deploy prod-5-myapp"
}
ok: [prod-6-myapp] => {
    "msg": "Deploy prod-6-myapp"
}

The group prod_2 shouldn't be deployed when prod_1 fails. Test it. For example

shell> ansible-playbook -i hosts playbook.yml -e "prod_1_failed=True"

gives

PLAY [prod_1] ****

  ...

PLAY [localhost] ****

TASK [fail] ****
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Test prod_1 failed"}

  ...