跳转至

Ansible playbook

  • https://blog.csdn.net/qq_35887546/article/details/105266675

1 特点

  • 默认按顺序执行每一个 task
  • 当一个 host 的 task 执行失败,这个 host 就被移除,属于这个 host 的其它 task 不会再执行

2 template

  • [文档] (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html#template-module)
  • 功能:将文件作为模板发送到目标主机。模板语法采用 Jinja2 templating language。template 也是一个模块。
  • 示例
$ tree 
.
├── hostname.yaml
└── templates
    └── test.j2
## hostname.yaml
---
- name: write hostname
  hosts: web
  gather_facts: True
  tasks:
  - name: write hostname using jinja2
    ansible.builtin.template:
      src: templates/test.j2
      dest: /tmp/hostname
My name is {{ ansible_facts['hostname'] }}

3 Handlers

  • 文档
  • 功能:在发生改变时运行服务。有时,您希望任务仅在计算机上发生更改时运行。例如,如果任务更新了服务的配置,但如果配置未更改,则可能需要重新启动该服务。Ansible 使用处理程序来解决这个用例。处理程序是仅在收到通知时才运行的任务。

3.1 语法

  • 使用 handlers 关键字。
  • handlers 也是一种 tasks,因此和 tasks 关键字 一样的缩进
  • tasks 中使用 notify 关键字,其内容是数组,可以指定多个 handler 的 name。
  • handlers 还有 listen 关键字,扮演这分组的效果,多个 handler 可以成为一组,notify 只需要触发这个分组即可,而不用指定多个 handler。这叫做 命名 handlers

3.2 示例

---
- name: Verify apache installation
  hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
    - name: Ensure apache is at the latest version
      ansible.builtin.yum:
        name: httpd
        state: latest

    - name: Write the apache config file
      ansible.builtin.template:
        src: /srv/httpd.j2
        dest: /etc/httpd.conf
      notify:
      - Restart apache

    - name: Ensure apache is running
      ansible.builtin.service:
        name: httpd
        state: started

  handlers:
    - name: Restart apache
      ansible.builtin.service:
        name: httpd
        state: restarted
  • listen:命名 handlers
tasks:
  - name: Restart everything
    command: echo "this task will restart the web services"
    notify: "restart web services"

handlers:
  - name: Restart memcached
    service:
      name: memcached
      state: restarted
    listen: "restart web services"

  - name: Restart apache
    service:
      name: apache
      state: restarted
    listen: "restart web services"

4 Blocks

  • 文档
  • 功能:块创建任务的 逻辑组。块还提供了处理任务错误的方法,类似于许多编程语言中的异常处理。
  • 语法:
    • 新增 block 关键字,属于 task 下的属性。
  • 示例
 tasks:
   - name: Install, configure, and start Apache
     block:       
     - name: Install httpd and memcached
         ansible.builtin.yum:
           name:
           - httpd
           - memcached
           state: present

     - name: Apply the foo config template
         ansible.builtin.template:
           src: templates/src.j2
           dest: /etc/foo.conf

    - name: Start service bar and enable it
         ansible.builtin.service:
           name: bar
           state: started
           enabled: True
     when: ansible_facts['distribution'] == 'CentOS'
     become: true
     become_user: root
     ignore_errors: true

5 Role

6 Include、import

在 2.16 版本后,关键字 include 被移除了,改用更细化的关键字 include_tasksinclude_role 等。

7 TASK [Gathering Facts] 执行很慢

原因是由于 Ansible 默认对远程主机执行任何一个 playbook 之前, 都会先通过 setup 模块获取 facts。它是从远程主机上自动收集的变量。包括主机名、内核版本、网卡、IP、环境变量等等信息,用于 ansible 后续的其他操作,所以特别费时间,通常如果不需要 facts 需要对其配置进行关闭。

  • 在 playbook 文件中添加 gather_facts: False 关闭 facts。
  • 示例
---
- name: create a directory and write some data
  gather_facts: False
  hosts: web
  remote_user: shuhw
  tasks:
  - name: mkdir a directory
    ansible.builtin.file:
      path: "/tmp/ansible_test"
      state: directory
  - name: touch a file
    ansible.builtin.file:
      path: "/tmp/ansible_test/1"
      state: touch
  - name: write some data
    ansible.builtin.shell: "free -hm > /tmp/ansible_test/1"

可以通过 debug 模块查看 facts 内容 (输出内容较多,包括一些硬件信息,如网卡信,cpu)

---
- name: Print all available facts
  gather_facts: True
  hosts: web
  remote_user: shuhw
  tasks:
    - name: Print all available facts
      ansible.builtin.debug:
        var: ansible_facts

8 变量

8.1 定义变量

8.1.1 在 playbook 定义

或者任意文件中定义,然后使用 vars_files 引入

---
- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - /vars/external_vars.yml

  tasks:

  - name: This is just a placeholder
    ansible.builtin.command: /bin/echo foo

8.1.2 在 inventory 中定义

ini 格式

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

yaml 格式

atlanta:
  hosts:
    host1:
    host2:
  vars:
    ntp_server: ntp.atlanta.example.com
    proxy: proxy.atlanta.example.com

8.1.3 命令行中定义

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

或者 json 格式

ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'

或者从文件中

ansible-playbook release.yml --extra-vars "@some_file.json"

8.2 引用变量

使用 Jinja2 语法引用定义的变量

ansible.builtin.template:
  src: foo.cfg.j2
  dest: '{{ remote_install_path }}/foo.cfg'

9 Module

9.1 默认模组参数

  • playbooks_module_defaults 如果经常使用相同的参数调用相同的模块,那么使用 MODULE_DEFAULTS 关键字为该特定模块定义默认参数会很有用。
- hosts: localhost
  module_defaults:
    ansible.builtin.file:
      owner: root
      group: root
      mode: 0755
  tasks:
    - name: Create file1
      ansible.builtin.file:
        state: touch
        path: /tmp/file1

    - name: Create file2
      ansible.builtin.file:
        state: touch
        path: /tmp/file2

    - name: Create file3
      ansible.builtin.file:
        state: touch
        path: /tmp/file3

MODULE_DEFAULTS 关键字可以用在 play, block, task 中

- block:
    - name: Print a message
      ansible.builtin.debug:
        msg: "Different message"
  module_defaults:
    ansible.builtin.debug:
      msg: "Default message"

可以用空的 {} 来取消设置的默认值

- name: Create file1
  ansible.builtin.file:
    state: touch
    path: /tmp/file1
  module_defaults:
    file: {}

10 Interactive 输出

  • playbooks_prompts 通过使用 vars_prompt 部分定义需要交互的信息,用户输入的数据,保存在变量中,再使用 jinja2 语法读取变量值。
    ---
    - hosts: all
      vars_prompt:
    
        - name: username
          prompt: What is your username?
          private: false
    
        - name: password
          prompt: What is your password?
    
      tasks:
    
        - name: Print a message
          ansible.builtin.debug:
            msg: 'Logging in as {{ username }}'