When is the best time to read a book? It’s when you first buy a book and get to know it while it’s fresh, and then finish it right away. If you miss the best time to read a book, when is the right time, when you need information or knowledge on the subject.

Recently I have been working on Ansible automation tools. See the Ansible How-to guide to get started. Mainly in order to achieve their own remote host related operations in the task, as a breakthrough point for learning.

Now that I’ve done my task, I’m ready to move on to other uses of Ansible. Here is my personal summary.


Experience:

  • The document is too extensive to master, so use the 2/8 rule to see what your colleagues are saying
  • Practical content, or need to write their own code, run, see the effect. When you run through your own code, chances are you’ve learned this
  • Here’s a quick way to start: If you need to solve a problem urgently, ask someone who has experience. If you are not in a hurry, try to understand the content first, then ask others. Repeat your questions.
  • Don’t be shy about asking questions. Time is precious.

The following summary is mainly based on examples:

  • First draft: discard all references and rely on empirical summing up
  • Second draft: Fill in the blanks
  • Third draft: correct the errors in the references and publish them

Outline:

  • Ansible. CFG Configuration file
  • variable
  • judge
  • cycle
  • Commonly used modules
    • debug
    • copy
    • file
    • shell
    • command
    • stat
    • unarchive
    • ping
    • template
    • user
    • group
    • service
    • get_url
  • include
  • role
    • The directory structure
    • Rely on
    • Execution order

Ansible is written in Python and works in a modular way, where the real action is handled by these modules. Ansible provides the overall framework.

1, install,

pip install ansible
Copy the code

Or install it according to the Linux version

apt-get install ansible
Copy the code

The management host must be Linux, and the node host must have Python and corresponding libraries.

Typically, both the management host and the node host are Linux.

2. Basic use

Run on the command line:

The command line mode is suitable for simple operations.

ansible all -m ping
Copy the code

The playbook operation:

The PlayBook lends itself to complex processing actions.

ansible-playbook example.yml
Copy the code

View supported modules:

ansible-doc -l
Copy the code

View the usage and supported parameters of a module:

ansible-doc -s ping
Copy the code

3. Configuration files

After the installation is complete, there are two files in the default directory:

/etc/ansible/hosts
/etc/ansible/ansible.cfg
Copy the code

The hosts file defines the IP address of the node host and the following configuration information.

The ansible. CFG file defines a global configuration file with many configuration items, which can be used to complete your daily tasks by default.

But in addition to the default generated ansible. CFG file, you can create one in your own project with the same name.

Ansible reads configuration files in the following order:

  • Defined in the ANSIBLE_CONFG environment variable
  • Ansible. CFG The current directory
  • * / ansible. CFG current user home/username/ansible CFG
  • /etc/ansible/ansible. CFG Specifies the default directory for generating files

What do you make of this information about reading configuration files?

Here’s an example:

# Current project structure

ansible:
---playbooks
---example
---leanr-ansible/example.yml
---ansible.cfg

Copy the code

You execute the ansible command in this directory

  • If the environment variable is not set, read the ansible. CFG configuration information in the current directory.
  • If the current directory is not set, search for configuration information in the home directory.
  • Otherwise, the configuration information generated by default is read.

4. Common modules

Example of operation

In this example, only the usage scenarios of these modules are understood and multiple steps are deliberately performed.

  • Copying management Nodes/home/ubuntu/zartclientUnder thezartclizartcli.iniFile to the node host/home/ubuntu/zartclient
  • Based on the previous step, copy/home/ubuntu/zartclient/zartcli/usr/bin/zartcli
  • Using the file you just copied on the node host, run the download command:Zartcli -o=download -i=admin -m=bin -n=op-cli -v=v0.0.3 -p=/home/ubuntu/downloadDownloaded to/home/ubuntu/downloaddirectory
  • Decompress the downloaded file to/paasdata/datadirectory
  • Copy the decompressed file from the host to the /etc/opcli directory
  • Copy the data on the node hostop-cli/usr/bin
  • On the node hostop-cli task listExecute the command
  • On the node hostop-cli node listExecute the command

In the age of fast reading, I don’t think anyone wants to watch these moves. Let’s draw a flow diagram.

Think of each step as a task.

Step 1: Check whether the corresponding file exists. If yes, copy it

Modules: stat, Copy, DEBUG, file

  • Check whether the remote node host has a folder
  • If no, create one
  • Copy the local file to the corresponding directory on the remote node host

- name: is /home/ubuntu/zartclient exists
  stat:
    path: /home/ubuntu/zartclient
  register: result
  
- name: show result 
  debug:
    msg: "{{result}}"
    
- name: create dest path in remote
  file:
    path: "{{ dest-path }}"
    state: direstory
  with_items:
    - "/home/ubuntu/zartclient"
  when: not result.stat.exists

- name: copy file to remote
  copy:
    src: "{{item.src}}"
    dest: "{{item.dest}}"
  with_items:
    - { src: "/home/ubuntu/zartclient/zartcli" dest: "/home/ubuntu/zartclient"}
    - { src: "/home/ubuntu/zartclient/zartcli.ini" dest: "/home/ubuntu/zartclient"}

- name: copy zartcli into /usr/bin
  copy:
    src: "{{item.src}}"
    dest: "{{item.dest}}"
  with_items:
    - { src: "/home/ubuntu/zartclient/zartcli", dest: "/usr/bin"}

Copy the code

As can be seen, processing corresponding actions, there are corresponding modules, modules with parameters, complete the task.

  • {{}}That’s the variable
  • With_items: is a list that represents loop fetching variables
  • Register: Assigns the result of the action to a variable, which is a map, and can obtain the contents according to the key value
  • When: indicates a judgment and operates according to the Boolean value of the result

Step 2: Check whether files exist. If yes, run the download command

The first step to copy the file is a client, mainly on the file upload, download, query and so on.

Modules: shell, command


- name: is /home/ubuntu/download exists
  stat:
    path: "{{item}}"
  with_items:
    - "/home/ubunt/download"
  register: result
 
- name: create /home/ubuntu/download
  file:
    path: "{{item}}"
    state: direstroy
  with_items:
    - "home/ubuntu/download"
  when: not result.stat.exists

- name: query op-cli
  command: "{{tools}} -o={{operate}} -i={{tenants}} -m={{type}} -n={{name}} \ -v={{version}}"
  vars:
      tools: zartcli
      operate: query
      tenants: admin
      type: bin name: op-cli version: v0.0.3 register: result-name: download op-clicommand: "{{tools}} -o={{operate}} -i={{tenants}} -m={{type}} -n={{name}} \ -v={{version}} -p={{path}}"
    vars:
      tools: zartcli
      operate: query
      tenants: admin
      type: bin
      name: op-cli
      version: v0.0.3
      path: /home/ubuntu/download


Copy the code
  • Item is a keyword that represents a variable
  • Item [0] can indicate that the variable is a list, where the first value of the list is represented
  • Item. SRC can indicate that the variable is a map, where the SRC value of the map is represented
  • Vars indicate that the module can be populated with values corresponding to custom variable names

Step 3: Unzip the downloaded files

The downloaded file in the second step is a tar package, which needs to be decompressed to a specified directory

Module: unarchive, file


- name: create /paasdata/data
  file:
    path: "/paasdata/data"
    state: direstory
    

- name: untar file
  unarchive:
    src: "{{src-path}}"
    dest: "{{dest-path}}"
    remote_src: yes
  vars:
    src-path: "/ home/ubuntu/download/admin_op_cli_v0. 0.3 / op - cli. Tar. Gz." "
    dest-path: "/paasdata/data"
    


Copy the code
  • Yes is no different from true
  • Remote_src: yes Indicates that the decompressed file is operated on the node host

Step 4: Copy the file

- name: create /etc/opcli
  file:
    path: "/etc/opcli"
    state: directory


- name: copy /paadata/data/conf||op-cli
  copy:
    src: "{{item.src}}"
    dest: "{{item.dest}}"
  with_items:
    - { src: "/paasdata/data/conf/common.yml" dest: "/etc/opcli/conf"}
    - { src: "/paasdata/data/op-cli" dest: "/usr/bin"}

Copy the code

Step 5: Execute the query command

- name: op-cli task list || op-cli node list
  command: "{{item[0]}} {{item[1]}} list"
  with_nested:
    - [ "op-cli" ]
    - ["task"."node"."nodepool"]

Copy the code
  • With_nested: nested loop

Op-cli task list, op-CLI node list, op-cli nodepool list

The previous eight movements were changed into five movements by borrowing some loops, that is, each of the five movements contains several movements.

It’s easy for beginners to do all of the above in one file: but there are better ways to do it.

# main.yml
---
- hosts: 10.62.60.21
  romote_user: root
  tasks:

    - name: one The first step #
    
    - name: two Step # 2
    
    - name: three Step # 3
    
    - name: four Step # 4
    
    - name: five Step # 5
    
    - name: six Step # 6.Copy the code

5、 include_tasks

If you want to write tasks that can be reused, it’s like abstracting functions in the programming world. Ansible provides such a mechanism. Split a large file into separate files. Import the file using the include_tasks method.

For example, the five steps above are to write files separately

  • zartclient.yml
  • download.yml
  • untarfile.yml
  • copyfile.yml
  • executecommand.yml

Playbook entry: mail.yml

Then main.yml is as follows:

--- - hosts: 10.62.60.21 root_usr: root tasks: -include_tasks: zartclient.yml -include_tasks: download.yml - include_tasks: untarfile.yml - include_tasks: copyfile.yml - include_tasks: executecommand.ymlCopy the code

Separate the processing actions from each other. Ready to reuse.

6, roles,

Include_tasks seems like a good way to organize ansible-playbook.

Ansible offers a better way to organize: Roles

Roles is based on a known file structure to automatically load certain vars_files, Tasks, and Handlers. Grouping content based on Roles makes it easy to share Roles with other users. This organization makes reuse easier. Each relatively independent processing action stands alone and can be applied to more complex scenarios.

A role file might include these:

  • Tasks file: Writes the processing actions of an independent module
  • Handlers file:
  • Vars file: Writes variables for a separate module
  • Meta files: Write dependencies where an independent module refers to another role
  • Defaults files: Default variable files
  • Templates file: template file
  • Files file

Note that you can have multiple files with the suffix yml in the folder, but you must have the main.yml file

The action above is reorganized using Roles as follows:

Directory:

├ ─ ansible │ ├ ─ the playbook │ └ ─ roles │ ├ ─ the download - bin │ │ ├ ─ the tasks │ │ └ ─ vars │ └ ─ op - cli │ ├ ─ meta │ ├ ─ the tasks │ └ ─ varsCopy the code

Download file into a download-bin role as an example to describe how to write a role.

tasks/deploy.yml


- name: download bin by zartcli
  command: "{{zartcli_cli_path}}/zartcli -o=download -i={{tenant_id}} -m={{bin_type}} \ -n={{bin_name}} -v={{bin_version}} -p={{download_path}}"
           
Copy the code

tasks/main.yml

---
- include_tasks: download.yml
  vars:
    zartcli_cli_path: "{{zartcli_clipath}}"
    tenant_id: "{{tenantid}}"
    bin_name: "{{binname}}"
    bin_version: "{{binversion}}"
    download_path: "{{downloadpath}}"
    bin_type: "{{bintype}}"

Copy the code

vars/main.yml

---
zartcli_clipath: "/home/cloud/zartclient"
tenantid: "admin"
binname: "op-cli"
binversion: "v0.0.3"
downloadpath: "/home/cloud/zartclidownload"
bintype: "bin"

Copy the code

Task /main.yml is the entry point for this role. Import download.yml and store all required variables in the var/main.yml file.

Other roles need to reuse this module:

op-cli/meta/main.yml

dependencies:
  - role: download-bin

Copy the code

So the op-CLI role can also have download actions.

Roles is suitable for projects with complex organizations where modules are handled independently and can be reused. Include_tasks has some disadvantages such as low module reusability and variable definition.

The above op-CLI role reuse download-bin, no need to define variables again.

One more thing worth noting is that the playBook is typically executed in the same order as tasks are defined.

After roles is used, Roles is executed in playBook first and then in the order defined by Tasks.

If you need to execute a task first or last, you can use pre_tasks and post_tasks.

  • pre_tasksThe first to perform
  • post-tasksThe last execution

Another use of ROLES requires configuring ansible.cfg

Roles_path = directory# is the directory where roles is located
Copy the code

7. References

  • The official documentation

It is not easy to explain these rational things in words, and it is difficult to express them in words in the future. I will record a video for practical operation. It might be easier for the reader to understand.