Tuesday, December 15, 2020

Ansible - Exception handling or error handling

Ansible: exception handling ...

1. Lets create a simple playbook and run
[root@master wk_dec15]# cat error.yaml
- hosts: w1
  tasks:
  - package:
      name: "httpd"
      state: present
  - debug:
      msg: "This is a test run .."
[root@master wk_dec15]# ansible-playbook error.yaml

2. Lets make a mistake on one of the variable.
say pkg name is nane
# cat error.yaml
- hosts: w1
  tasks:
  - package:
        nane: "httpd"
        state: present
- debug:
    msg: "This is just a test run ..."
[root@master wk_dec15]# alias 'ap=ansible-playbook'
[root@master wk_dec15]# ap error.yaml
we saw fatal error. we know its because the keyword we wrote, ansible does not that that keyword defined.
in fact it didn't recognize the parameter e=we supply.

3. What we can do is tell ansible to ignore if you find error. do not just throw error, continue.
# cat error.yaml
- hosts: w1
  tasks:
  - package:
        nane: "httpd"
        state: present
    ignore_errors: yes # ignore this error and go to next task
- debug:
    msg: "This is just a test run ..."
[root@master wk_dec15]# ap error.yaml
You see, error is ignored this time.

4. Now, lets try something else, lets download a file from internet..
[root@master wk_dec15]# ansible-doc -l uri
# cat errors.yaml
- hosts: w1
  tasks:
    - package:
        name: "httpd"
        state: present
debug: 
   msg: "This is just testing msg"
Before running the playbook to download a file from internet, lets look into some docs
or google for ansible uri or get-uri
look for example 
Image source: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg

[root@master wk_dec15]# cat error.yaml
- hosts: w1
  tasks:
  - package:
      nane: "httpd"
      state: present
    ignore_errors: yes
  #- get_uri:
  - uri:
      url: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
      dest: "/var/www/html/life_l.jpg"
  - debug:
      msg: "This is a test run .."
[root@master wk_dec15]#

[root@master wk_dec15]# ap error.yaml
[root@worker1 ~]# ls -l /var/www/html/life_l.jpg
-rw-r--r--. 1 root root 206868 Dec  8 05:10 /var/www/html/life_l.jpg
The result above shows that its successful.

5. Now, say we have a problem with internet connection, and if you run this playbook,, it will fail.
It will throw error, so how do you handle the error?
The best thing you can do is ignore the error. How? look at the yaml file below..
[root@master wk_dec15]# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.10.1    0.0.0.0         UG        0 0          0 enp0s3
for lab purpose, you can remove the 0.0.0.0
[root@master wk_dec15]# cat error.yaml
- hosts: w1
  tasks:
  - package:
      nane: "httpd"
      state: present
    ignore_errors: yes
  #- get_uri:
  - uri:
      url: https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/quotes-about-change-1580499303.jpg
      dest: "/var/www/html/life_l.jpg"
    ignore_errors: yes
  - debug:
      msg: "This is a test run .."
[root@master wk_dec15]# ap error.yaml
If you are disconnected from internet, it will fail with error unreachable network. 
so, you can use ignore_errors keyword to ignore the error.
it will continue to run it. But it might be an important piece of information, that you can't ignore it.
so,  you have to be very careful while dealing with ignore_errors.

6. Using block.
On block, your code in block and at the end, include rescue.


[root@master wk_dec15]# ap error.yaml
/usr/lib/python3.6/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.2) or chardet (3.0.4) doesn't match a supported version!
  RequestsDependencyWarning)
PLAY [w1] *********************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************
ok: [w1]
TASK [package] ****************************************************************************************************************
ok: [w1]
TASK [uri] ********************************************************************************************************************
changed: [w1]
TASK [service] ****************************************************************************************************************
changed: [w1]
TASK [debug] ******************************************************************************************************************
ok: [w1] => {
    "msg": "This is a test run .."
}
TASK [debug] ******************************************************************************************************************
ok: [w1] => {
    "msg": "This is a test run .."
}
PLAY RECAP ********************************************************************************************************************
w1                         : ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@worker1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2020-12-08 06:01:59 EST; 42s ago
     Docs: man:httpd.service(8)
 Main PID: 59114 (httpd)

[root@worker1 html]# ls -ltr
total 212
-rw-r--r--. 1 root root      8 Dec  7 03:19 index.html
-rw-r--r--. 1 root root     12 Dec  8 05:51 webap.htm
-rw-r--r--. 1 root root 206868 Dec  8 05:53 life_l.jpg
[root@worker1 html]# cat webap.htm
This is cool
===================================
Notes
exception handling
- error handling
Ansible is a Framework...
- Declarative language
- Code - playbook  - error - exception
- YAML

How we can handle error or exceptions

yaml code for package [ DL]
- package: # keywork - a module
    nane: "httpd" # what is nane? I don't understand, its not on my voculabulary...
    state: present
You ask me to perform something that I don't know.. I will terminate everything... - default behavior
but we don't want to do that. Run this task, if there is minor mistake, keep trying it. if you don't understand
something, just ignore and keep executing it... execute other tasks, skip the one with error..
how ansible handle this kind of situation?


block
try 
-----
-----
----
catch .. except ... rescue
app does not crash - good programmer...
check your inventory file
#  cat /root/myhosts
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - debug:
        msg: "This is a test ..."
Run it
# ap error.yaml
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      name: "httpd"
      state: present
  - debug:
        msg: "This is a test ..."
# ap error.yaml
running fine now...
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      nane: "httpd"
      state: present
  - debug:
        msg: "This is a test ..."

it throws error since the keywork is bad

# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      name: "httpd"
      state: present
    ignore_errors: yes # ignore the error and go to next step
  - debug:
        msg: "This is a test ..."
But it is not always a good practice to ignore the error.
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      name: "httpd"
      state: present
    ignore_errors: yes # ignore the error and go to next step
    url: http://mywebsite.internet # lets say this task must run, but if you ignore, whole thing will fails if there is not internet connection.
    ignore_errors: yes # not always a good idea. they skip the task.
  - debug:
        msg: "This is a test ..."

Try and catch ..rescue

go to ansible doc and look for uri
# ansible-doc -l uri
or google for ansible uri
look through all option and go all the way down, to example.
or google for ansible get-url # download file from somewhere..
go to internet and get an URL for any picture.

https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg


# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      name: "httpd"
      state: present
#  - get_url: # this module is created by a developer.. and you have to follow certain property..
  - uri
      url: "https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg"
      dest: "/var/www/html/life.jpg"
  - service:
      name: "httpd"
      state: started
  - debug:
        msg: "This is a test ..."


run the code, and should be able to download.
Delete your default route
# route del net 0.0.0.0
now you have internal connectivity but not internet connectivity.
run run the playbook again,
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      name: "httpd"
      state: present
  - get_url: # this module is created by a developer.. and you have to follow certain property..
      url: "https://disabledparenting.com/wp-content/uploads/2017/02/lifeisbeautiful-e1458411303728-300x162.jpg"
      dest: "/var/www/html/life.jpg"
  - service:
      name: "httpd"
      state: started
  - debug:
        msg: "This is a test ..."
# ap error.yaml
it will fail.. and error says ..
it is trying to go to internet .. ther eis not network connectivity,, unreachable...
if something does not work, throw the error.
Now, how do we handle it?
What we can do? ignore error ..
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
  - package:
      name: "httpd"
      state: present
  - get_url:
       url: "https://url.com/myimage.jpg"
       dest: "/var/www/html/life.jpg"
     ignore_errors: yes
  - service:
      name: "httpd"
      state: started
  - debug:
        msg: "This is a test ..."
# ap error.yaml
now, it skips the error part..
This is a bad practice. What we can do is block
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
    block:
    - package:
        name: "httpd"
        state: present
    - get_url:
         url: "https://url.com/myimage.jpg"
         dest: "/var/www/html/life.jpg"
       # ignore_errors: yes
    - service:
        name: "httpd"
        state: started
    - debug:
          msg: "This is a test ..."
Run this play
# ap error.yaml
we see errors
when you use block, you have to use rescue at the end..
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
   - block:
      - package:
          name: "httpd"
          state: present
 #     - get_url:
           uri:
           url: "https://url.com/myimage.jpg"
           dest: "/var/www/html/life.jpg"
         # ignore_errors: yes
      - service:
          name: "httpd"
          state: started
      - debug:
            msg: "This is a test ..."
      - debug:
          msg: "For rescue ..."


re-run it.
but this time, as soon error comes, last time, it failed, this time, it continue running ..

# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
   - block:  # module . runs other modules..
      - package:
          name: "httpd"
          state: present
#      - get_url:
           uri:
           url: "https://url.com/myimage.jpg"
           dest: "/var/www/html/life.jpg"
         # ignore_errors: yes
      - service:
          name: "httpd"
          state: started
      reacue:
      - copy:
          dest: "/var/www/html/kb.jpg"
          content: "Hi How are you?"
      - debug:
            msg: "This is a test ..."
      rescue:
      - debug:
          msg: "For rescue ..."
run it again,
using finally for block..
# cat eorrr.yml
- hosts: 192.168.10.20
  tasks:
   - block:  # module . runs other modules..
      - package:
          name: "httpd"
          state: present
 #     - get_url:
           uri:
           url: "https://url.com/myimage.jpg"
           dest: "/var/www/html/life.jpg"
         # ignore_errors: yes
      - service:
          name: "httpd"
          state: started
      reacue:
      - copy:
          dest: "/var/www/html/kb.jpg"
          content: "Hi How are you?"
      - debug:
            msg: "This is a test ..."
      rescue:
      - debug:
          msg: "For rescue ..."
     always:   # block, rescue, always are on sam indent
     - debug: # testing message
           msg: "mail to this group ..." 


google for mail
# ansible-docs  -l | grep mail
community.general.mail
# ansible-docs mail
look for module sending mail...
if you want to use this module, there are some sort challanges regarding security.

lets talk about vault - 
how to mail?

gmail.com -> application - web or app
--- opens with https -> 
where do you want to send?
to send email,
webapp collect all info such as 
to
sub
body
from
google has its own mail server,
on your behalf, the gmail application written is some language (php ..) collects info and mail server 

we can use
- webUI
- you can directly go to mail server from your pc..(for automation)
- authlogin - login 
emialid: 
google for google mail smtp server ip address ...

# cat 
- hosts: 127.0.0.1
  tasks:
  mail:
    host: smtp.gmail.com
    portL 587
    username: sam@gmail.com
    password: your_passsword
    to: hr@abc.com
    subject: ansible Class
    body: system {{ ansible_host }} has been successfully provisioned.
you have to type your pw, inorder to run it. But we don't want to share our pw so people can use our email pw.
but for testing purpose, use it and verify if it infact works.. do not share the code with your pw.
interrupt/exception -> Whats the difference
ctrl+C is interruption -> 

=============================================================






No comments:

Post a Comment

Git branch show detached HEAD

  Git branch show detached HEAD 1. List your branch $ git branch * (HEAD detached at f219e03)   00 2. Run re-set hard $ git reset --hard 3. ...