# Playbook Example

* In here I will examile a real use case example by creating and executing Ansible playbooks. I will install Nginx in all hosts and explore the different options for targeting OS variations with Ansible packages.
* Use Ansible to install and configure project website, taking into account variances between the linux distributions of Nginx on both CentOS and Ubuntu.
* Use Jinja2 templates to customise the website.

Let's first create our ansible config file `ansible.cfg`:

```
[defaults]
inventory = hosts
host_key_checking = False
```

Next our group vars for centos and ubuntu hosts:

`group_vars/centos`:

```
---
ansible_user: root
...
```

`group_vars/ubuntu`:

```
---
ansible_user: root
...
```

Next our host file `hosts`:

```
[control]
ubuntu-c

[centos]
centos[1:3]

[ubuntu]
ubuntu[1:3]

[linux:children]
centos
ubuntu
```

Next our playbook itself for installing EPEL on CentOS hosts:

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

  # Handlers: the list of handlers that are executed as a notify key from a task

# Three dots indicate the end of a YAML document
...
```

Now we can execute the playbook:

```
$ ansible-playbook nginx_playbook.yaml 

PLAY [linux] *****************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************
ok: [centos2]
ok: [centos1]
ok: [centos3]
ok: [ubuntu1]
ok: [ubuntu2]
ok: [ubuntu3]

TASK [Install EPEL] ******************************************************************************************************************************
skipping: [ubuntu1]
skipping: [ubuntu2]
skipping: [ubuntu3]
changed: [centos1]
changed: [centos3]
changed: [centos2]

PLAY RECAP *******************************************************************************************************************
centos1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
centos2                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
centos3                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
ubuntu1                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
ubuntu2                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
ubuntu3                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
```

Now let's install Nginx in all hosts by slightly modifying the playbook `nginx_playbook.yaml`:

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx CentOS
      yum:
        name: nginx
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx Ubuntu
      apt:
        name: nginx
        update_cache: yes
        state: latest
      when: ansible_distribution == 'Ubuntu'

  # Handlers: the list of handlers that are executed as a notify key from a task

# Three dots indicate the end of a YAML document
...
```

Once we execute it, the output should be something similar to below:

```
$ ansible-playbook nginx_playbook.yaml

PLAY RECAP *******************************************************************************************************************
centos1                    : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
centos2                    : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
centos3                    : ok=3    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
ubuntu1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
ubuntu2                    : ok=2    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
ubuntu3                    : ok=2    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0
```

or we can simply use Nginx module for that like below in `nginx_playbook.yaml`:

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx
      package:
        name: nginx
        state: latest

  # Handlers: the list of handlers that are executed as a notify key from a task

# Three dots indicate the end of a YAML document
...
```

Next let's add a task to restart Nginx in our playbook:

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx
      package:
        name: nginx
        state: latest

    - name: Restart nginx
      service:
        name: nginx
        state: restarted

  # Handlers: the list of handlers that are executed as a notify key from a task

# Three dots indicate the end of a YAML document
...
```

Now let's had a handler to add a http health check to make sure Nginx is running:

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx
      package:
        name: nginx
        state: latest

    - name: Restart nginx
      service:
        name: nginx
        state: restarted
      notify: Check HTTP Service

  # Handlers: the list of handlers that are executed as a notify key from a task
  handlers:
    - name: Check HTTP Service
      uri:
        url: http://{{ ansible_default_ipv4.address }}
        status_code: 200 

# Three dots indicate the end of a YAML document
...
```

Next let's create group vars for HTML location for Nginx in different hosts, and create a jinja template for HTML.

First let's nodify the playbook to deploy the HTML file inside Nginx:

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx
      package:
        name: nginx
        state: latest

    - name: Restart nginx
      service:
        name: nginx
        state: restarted
      notify: Check HTTP Service

    - name: Template index.html-base.j2 to index.html on target
      template:
        src: index.html-base.j2
        dest: "{{ nginx_root_location }}/index.html"
        mode: 0644

  # Handlers: the list of handlers that are executed as a notify key from a task
  handlers:
    - name: Check HTTP Service
      uri:
        url: http://{{ ansible_default_ipv4.address }}
        status_code: 200 

# Three dots indicate the end of a YAML document
...
```

Next our group vars for centos and ubuntu hosts:

`group_vars/centos`:

```
---
ansible_user: root
nginx_root_location: /usr/share/nginx/html
...
```

`group_vars/ubuntu`:

```
---
ansible_user: root
nginx_root_location: /var/www/html
...
```

Now let's add the `ansible_managed` variable in the `ansible.cfg`:

```
[defaults]
inventory = hosts
host_key_checking = False
ansible_managed = Managed by Ansible - file:{file} - host:{host} - uid:{uid}
```

Now we can use the `ansible_managed` variable inside any of our templates.

Now let's load out variables in the playbook.

```
---
# YAML documents begin with the document separator ---

# The minus in YAML this indicates a list item.  The playbook contains a list
# of plays, with each play being a dictionary
-

  # Hosts: where our play will run and options it will run with
  hosts: linux

  # Vars: variables that will apply to the play, on all target systems
  vars_files:
    - vars/logos.yaml

  # Tasks: the list of tasks that will be executed within the play, this section
  # can also be used for pre and post tasks
  tasks:
    - name: Install EPEL
      yum:
        name: epel-release
        update_cache: yes
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: Install Nginx
      package:
        name: nginx
        state: latest

    - name: Restart nginx
      service:
        name: nginx
        state: restarted
      notify: Check HTTP Service

    - name: Template index.html-logos.j2 to index.html on target
      template:
        src: index.html-logos.j2
        dest: "{{ nginx_root_location }}/index.html"
        mode: 0644

  # Handlers: the list of handlers that are executed as a notify key from a task
  handlers:
    - name: Check HTTP Service
      uri:
        url: http://{{ ansible_default_ipv4.address }}
        status_code: 200 

# Three dots indicate the end of a YAML document
...
```

Add unarchive task in the playbook to unarchive the code of our hidden game.

```
    - name: Unarchive playbook stacker game
      unarchive:
        src: playbook_stacker.zip
        dest: "{{ nginx_root_location }}"
        mode: 0755
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://isurus.gitbook.io/infrastructure-and-platform-notes/ansible-5/06-playbooks-example.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
