ansible--playbook

playbook语法

playbook使用YAML语法描述配置文件,总的来说具有以下特性:

  • 需要以“---”开始,且需顶行手写
  • 此行开始正常些playbook的内容
  • 使用 # 号注释代码
  • 缩进必须是统一的,不能讲空格和Tab混用。
  • 缩进的级别必须是一致的。
  • 大小写敏感。
  • key/value值可同行写也可以换行写,同行使用:,换行需要以-分隔
  • 一个name只能包括一个task。

playbook小技巧

限定执行范围

--limit

可以使用该关键字限定一台或多台主机

ansible-playbook playbook.yml --limit local

--list-hosts

如果想知道在执行playbook时哪些主机受到影响,可以使用该关键字

用户与权限设置

--remote-user

指定用户

--ask-sudo-pass

传递sudo密码到远程主机

--sudo

强制play使用sudo用户

ansible-playbook playbook.yml --sudo --sudo-user=docker --ask-sudo-pass

Handlers

Handlers类似于编程语言中的钩子函数,可以在某一task执行完毕后,使用notify关键字进行调用。

Handlers的使用

Handlers的基本使用
Handlers应定义在任务之前,使用notify关键字进行调用后,会自动读取名称相同的Handlers。

handlers:
    - name: restart apache
       service: name=apache2 state=restarted
tasks:
    - name: 开启apache rewrite模块
    apache2_module: name=rewrite state=present
    notify: restart apache

调用多个

notify: 
    - restart apache
    - restart memcached

嵌套调用

handlers:
    - name: restart apache
       service: name=apache2 state=restarted
       notify: restart memcached

Handlers的一些注意事项

  • Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务重定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。
  • Handlers只会在Play的末尾运行一次;如果想在一个Playbook的中间运行Handlers,则需要使用meta模块来实现,例如:- meta: flush_handlers
  • 如果一个Play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用mega模块的--force-handlers选项来强制执行Handlers,即使是Handlers所在的Play中途运行失败也能运行。

变量

Playbook变量

在Playbook中,最常见的定义变量的方法是使用vars代码块。

---
- hosts: local
    vars: 
        key: value
    tasks:
        - debug: msg="Variable 'key' is set to {{ key }}"

同时,变量的定义也可以在一个独立的文件中完成,方法是在Playbook中使用vars_files代码块来引用。

---
- hosts: local
  vars_files:
    - vars.yml
  tasks:
    - debug: msg="Variable 'key' is set to {{ key }}"
# vars.yml内容如下
---
key: value

利用Ansible的内置环境变量实现变量配置未见的有条件导入。

当前生产环境中又多台主机,分别安装了CentOS系统和Debian系统,同时为两套系统设置两个变量定义文件:apache_CentOS.yml和apache_default.yml,进行如下配置

---
- hosts: local
    var_files:
        - ["apache_{{ ansible_os_family }}.yml", "apache_default.yml"]
    tasks:
        - service: name={{ apache }} state=running

在执行Playbook过程中,Ansible会先尝试读取对应名称的变量定义文件,如果没找到,会读取apache_default.yml

注册变量

注册变量,其实就是将操作的结果,包括标准输出和标准错误输出,保存到变量中,然后再根据这个变量的内容来决定下一步的操作,在这个过程中用来保存操作结果的变量就叫注册变量。

注册变量使用register关键字进行注册,注册完毕后可以通过stdout标准输出和stderr错误输出来读取注册变量的内容。

主机变量和组变量

主机变量和组变量的定义有两种方式,第一种可以直接定义在inventory文件中

# 主机变量,只对对应的主机生效
[local]
server1 key=value

# 组变量,只对当前组生效
[local:vars]
key=value

第二种方式定义在group_vars和host_vars目录中

在Ansible目录中新建目录group_varshost_vars,变量文件的名称要对应组或者主机的名称,然后在文件中以key:value的形式定义变量。

同时也可以在这两个文件夹下定义all.yml文件,来为所有主机组合主机定义变量。

要获取某一远程主机的变量可以使用{{ hostvars['server1']['key'] }}的方式

变量的优先级

以下变量优先级由高到低

  • 命令行中定义的变量(用-e定义的变量)
  • 在Inventory中定义的连续变量(比如ansible_ssh_user)
  • 大多数的其他变量(命令行装换、play中的变量、included的变量、role中的变量等)
  • 在Inventory中定义的其他变量
  • 有系统通过gather_facts方法发现的Facts
  • “Role默认变量”

if/then/when——流程控制

when关键字

需要在特定条件下才能执行的语句,使用when关键字进行定义。

- shell: php --version
register: php_version
-shell: yum -y downgrade php*
when: "'7.0' in php_version.stdout"

changed_when、failed_when

有时候Ansible的任务返回结果无论成功失败都是changed,我们可以使用changed_when手动标识任务的成功状态。

---
- hosts: local
    tasks:
        -name: Install dependencies
        command: "composer global require phpunit/phpunit --prefer-dist"
        register: composer
        changed_when: "'Nothing to install or update' not in composer.stdout"

Tags标签

默认情况下,Ansible在执行一个Playbook时,会执行Playbook中定义的所有任务。Ansible的标签功能可以给角色(Roles)、文件、单独的任务甚至整个Playbook打上标签,然后利用这些标签来指定要运行Playbook中的个别任务,或不执行指定的任务。

---
- hosts: local
    # 给整个Playbook所有任务打标签
    tags: deploy
    roles: 
        # 给角色打标签
        - { role: tomcat, tags: ['tomcat', 'app'] }
    tasks:
        - name: ping
            command: "ECHO 'Hello World'"
            # 给单独的任务打标签
            tags: 
                - hello

执行特定的Tags任务

# 执行标签任务
ansible-playbook test.yml --tags "hello"
# 不执行标签任务
ansible-playbook test.yml --skip-tags "hello"

Block块

块功能可以将任务进行分组,可以在块级别上应用任务变量。

---
- hosts: local
  tasks:
    # Install and configure Apache on RedHat/CentOS hosts.
    - block:
        - yum: name=httpd state=present
        - template: src=httpd.comf.j2 dest=/etc/httpd/conf/httpd.conf
        - service: name=httpd state=started enabled=yes
    when: ansible_os_family == 'RedHat'
    sudo: yes
    
    # Install and configure Apache on Debian/Ubuntu hosts.
    - block:
        - apt: name=apache2 state=present
        - template: src=httpd.conf.j2 dest=/etc/apache2/apache2.conf
        - service: name=apache2 state=started enabled=yes
    when: ansible_os_family == 'Debian'
    sudo: yes

使用块功能处理任务的异常

---
- hosts: local
  tasks:
    - block:
        - name: test
          script: monitoring-connect.sh
        rescue:
          - name: 只有脚本报错时才执行
            debug: msg="error"
        always:
          - name: 无论结果如何都执行
            debug: msg="always"

Includes

Includes可以引用文件,已达到代码复用的效果,不仅可以引用YML文件,还可以引用Vars、Handlers、Files文件

---
- hosts: local
    tasks:
        - include: included.yml
            # 带条件引入
            when: 1 in [1, 2, 3]

Roles

Roles可以通过特定的目录结构自动引入和该Roles相关的文件,已达到解耦和复用的目的。

基本用法

# 在根目录下创建对应文件夹,在创建main.yml,添加Roles后,会自动读取Main.yml的内容
mkdir -p roles/deploy/tasks
cd roles/deploy/tasks
touch main.yml
# 引入Roles
---
- hosts: local
    roles:
        - deploy

变量

Roles会自动读取同名Roles目录同名目录下的vars目录的main.yml文件中定义的变量,无需引入。

原文地址:https://www.cnblogs.com/peilanluo/p/11891838.html