Location>code7788 >text

Not for the faint of heart - a detailed explanation of the usage of roles in ansible-playbook

Popularity:11 ℃/2024-12-10 17:46:51

preamble

This article details the various uses of roles in the ansible-playbook, which allows you to bring together related tasks, variables, processors, files, templates, etc., so that they can be reused in different projects.

environmental preparation

assemblies releases
operating system Ubuntu 22.04.4 LTS
ansible 2.17.6

basic usage

file structure

.
├── 
├── 
└── roles
    └── base
        └── tasks
            └── 

  • As a list file for the target machine
    ▶ cat 
    10.22.11.166
    
  • As an entry file
    ▶ cat 
    - name: deploy
      hosts: all
      remote_user: wilson
      gather_facts: no
      vars:
        ansible_ssh_pass: '123456'
        ansible_python_interpreter: /usr/bin/python3
      roles:
        - base
    
    • name: Specifies the name of the job: deploy
    • hosts:allRepresents all the machines in the file (you can also specify categorization information for the machines)
    • remote_user: the login user of the target machine
    • gather_facts: If or not the basic data of the target machine should be gathered, the default is to gather it. The script specifies not to collect, to improve execution speed
    • vars.ansible_ssh_oass: password for the target machine login user
    • vars.ansible_python_interpreter: path to target machine python3
    • roles: specify the roles used for this jobbase
  • The roles directory serves as a collection of job tasks in ansible-playbook, and one of the collections is namedbase
    • Actions in Tasksbaseentry file for the
      ▶ cat roles/base/tasks/
      - name: first
        command: echo 'hello world'
      
      • baseThere is currently only 1 task, which is to log into the target machine and perform thehello world

(of a computer) run

▶ ansible-playbook -i  

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
changed: [10.22.11.166]

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Display the results of the execution on the screen

Needs remodelingroles/base/tasks/

▶ cat roles/base/tasks/
- name: first
  command: echo 'hello world'
  register: display_result
- name: display
  debug:
    msg: "{{ display_result }}"

Put the result into a variabledisplay_resultand then print it out through the template language and in json format

Running:

▶ ansible-playbook -i  

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
changed: [10.22.11.166]

TASK [base : display] ********************************************************************************************
ok: [10.22.11.166] => {
    "msg": {
        "changed": true,
        "cmd": [
            "echo",
            "hello world"
        ],
        "delta": "0:00:00.002740",
        "end": "2024-11-19 07:22:22.226036",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2024-11-19 07:22:22.223296",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "hello world",
        "stdout_lines": [
            "hello world"
        ]
    }
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Referencing Environment Variables

Passing in the operating system's environment variables can be done via thelookupto refer to it, e.g., to use PATH, you can pass thelookup('env', 'PATH')

Modification of roles/base/tasks/

▶ cat roles/base/tasks/
- name: first
  debug:
    msg: "{{ lookup('env', 'PATH') }}"

Running:

▶ ansible-playbook -i  

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "/home/wilson/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/usr/local/go/bin:/usr/local/go/bin"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Using ansible variables

The ansible variables here are partly ansible's default variables and partly ansible's default way of collecting basic information about the target machine, such as the operating system, cpu, memory, disk, and so on, when ansible is running.

selected built-in variables

variable name descriptive
inventory_hostname Hostname of the current task execution (from the Inventory file)
ansible_facts Contains all collected host facts (facts)
hostvars A collection of all host variables containing the current and other hosts

Collect basic information about the target machine

You need to turn on the switch that previously captured ansible's basic information.gather_facts: yesWhen you open it, it sacrifices speed.

Modification of roles/base/tasks/

- name: first
  debug:
    msg: "{{ hostvars }}"

Running:

Because the amount of data is too large, only part of the display, and json format, you can take the desired value directly

▶ ansible-playbook -i  

PLAY [deploy] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [10.22.11.166]

TASK [base : first] ************************************************************
ok: [10.22.11.166] => {
    "msg": {
        "10.22.11.166": {
            "ansible_all_ipv4_addresses": [
                "10.22.11.166"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::a00:27ff:fef6:82c4"
            ],
            "ansible_apparmor": {
                "status": "enabled"
            },
            "ansible_architecture": "x86_64",
            "ansible_bios_date": "12/01/2006",
            "ansible_bios_vendor": "innotek GmbH",
            "ansible_bios_version": "VirtualBox",
            "ansible_board_asset_tag": "NA",
            "ansible_board_name": "VirtualBox",
            "ansible_board_serial": "NA",
            "ansible_board_vendor": "Oracle Corporation",
            ...
            "inventory_dir": "/home/wilson/workspace/ansible",
            "inventory_file": "/home/wilson/workspace/ansible/",
            "inventory_hostname": "10.22.11.166",
            "inventory_hostname_short": "10.22.11.166",
            "module_setup": true,
            "playbook_dir": "/home/wilson/workspace/ansible"
        }
    }
}

PLAY RECAP *********************************************************************
10.22.11.166               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Whether to collect basic information about the target

As demonstrated above, justgather_facts: yescan immediately (do sth)

Passing variables from the command line

ansible-playbook can be accessed via the-eIncoming variable usage

▶ cat roles/base/tasks/
- name: first
  debug:
    msg: "{{ app_name }} - {{ app_version }}"

Running:

▶ ansible-playbook -i  -e "app_name=prom app_version=1.0" 

PLAY [deploy] ****************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************
ok: [10.22.11.166]

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "prom - 1.0"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Dynamic selection of host

1) Grouping hosts together

Modification of documents

▶ cat 
[ga]
10.22.11.166

[gb]
10.22.11.166
127.0.0.1

2) Modification of the entry file

▶ cat 
- name: deploy
  hosts: '{{h}}'
  remote_user: wilson
  gather_facts: no
  vars:
    ansible_ssh_pass: '123456'
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - base

Change the hosts in to be'{{h}}', dynamically defined by passing in the h variable

3) Running

indicate clearly and with certaintyhga

▶ ansible-playbook -i  -e "h=ga" 

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

indicate clearly and with certaintyhgb

▶ ansible-playbook -i  -e "h=gb" 

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world"
}
ok: [127.0.0.1] => {
    "msg": "hello world"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Conditional selection when

▶ cat roles/base/tasks/
- name: first
  debug:
    msg: "version 1"
  when: version == '1'

- name: second
  debug:
    msg: "version 2"
  when: version == '2'

Defining Temporary Variables

pass (a bill or inspection etc)-eIncoming variables to generate temporary variables

- name: first
  set_fact:
    tag: "hello-{{ version }}"

- name: second
  debug:
    msg: "{{ tag }}"

Running:

▶ ansible-playbook -i  -e "version=2" 

...

TASK [base : second] *********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello-2"
}

...

Calling multiple roles

1) New role: advance

.
├── 
├── 
└── roles
    ├── advance
    │   └── tasks
    │       └── 
    └── base
        └── tasks
            └── 

2) Directly referenced in the entry file

.
├── 
├── 
└── roles
    ├── advance
    │   └── tasks
    │       └── 
    └── base
        └── tasks
            └── 

Running:

▶ ansible-playbook -i  -e "version=2" 

PLAY [deploy] ****************************************************************************************************

TASK [base : first] **********************************************************************************************
ok: [10.22.11.166]

TASK [base : second] *********************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello-2"
}

TASK [advance : new-first] ***************************************************************************************
ok: [10.22.11.166] => {
    "msg": "new hello world"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3) In rolesbaseembedded inadvance

▶ cat 
- name: deploy
  hosts: all
  remote_user: wilson
  gather_facts: no
  vars:
    ansible_ssh_pass: '123456'
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - base

▶ cat roles/base/tasks/
- name: base first
  debug:
    msg: "base {{ version }}"

- name: base second
  include_role:
    name: advance
  vars:
    role_pipe_from_base: "hello world from base"

- name: base third
  debug:
    msg: "{{ role_pipe_from_advance }}"
▶ cat roles/advance/tasks/
- name: advance first
  debug:
    msg: "advance {{ version }}"

- name: advance second
  debug:
    msg: "{{ role_pipe_from_base }}"

- name: advance third
  set_fact:
    role_pipe_from_advance: "hello world from advance"

Running:

▶ ansible-playbook -i  -e "version=2" 

PLAY [deploy] ****************************************************************************************************

TASK [base : base first] *****************************************************************************************
ok: [10.22.11.166] => {
    "msg": "base 2"
}

TASK [base second] ***********************************************************************************************
included: advance for 10.22.11.166

TASK [advance : advance first] ***********************************************************************************
ok: [10.22.11.166] => {
    "msg": "advance 2"
}

TASK [advance : advance second] **********************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world from base"
}

TASK [advance : advance third] ***********************************************************************************
ok: [10.22.11.166]

TASK [base : base third] *****************************************************************************************
ok: [10.22.11.166] => {
    "msg": "hello world from advance"
}

PLAY RECAP *******************************************************************************************************
10.22.11.166               : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

This example presents:

  • input variableversionIt's shared.
  • How to pass parameters in role
  • Temporary variables defined during executionrole_pipe_from_advanceCross-role persistence is possible
  • Multi-role execution is serialized

wrap-up

  • Contact me for an in-depth chat


This concludes this article
I'm not very knowledgeable, so if there is any soup leakage, please do not hesitate to give me advice...