Ansible 进阶 (2) playbook Var

1 基本语法

执行 deploy.yml

ansible-playbook deploy.yml

查看输出的细节

[root@controller ~]# ansible-playbook test.yml --verbose
Using /etc/ansible/ansible.cfg as config file

PLAY [test content] *******************************************************************************************************************************************************************************************

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

TASK [add content] ********************************************************************************************************************************************************************************************
changed: [192.168.143.192] => {"changed": true, "cmd": "echo \"Im awcloud\" >>  /tmp/playbooktest.txt", "delta": "0:00:00.003959", "end": "2022-04-08 11:44:55.482102", "rc": 0, "start": "2022-04-08 11:44:55.478143", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

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

查看该脚本影响哪些hosts

[root@controller ~]# ansible-playbook test.yml --list-hosts

playbook: test.yml

  play #1 (web1): test content  TAGS: []
    pattern: ['web1']
    hosts (1):
      192.168.143.192
[root@controller ~]#

并行执行脚本

[root@controller ~]# ansible-playbook test.yml -f 10

PLAY [test content] *******************************************************************************************************************************************************************************************

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

TASK [add content] ********************************************************************************************************************************************************************************************
changed: [192.168.143.192]

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

2 基本结构

1.在什么机器上以什么身份执行
hosts
users
…

2.执行的任务是都有什么
tasks

3.善后的任务都有什么
handlers

例:

---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
  handlers:
    - name: restart apache
      service: name=httpd state=restarted

2.1 Tasks

tasks是从上到下顺序执行,如果中间发生错误,那么整个playbook会中止。修改文件后,再重新执行。

每一个task的对module的一次调用。使用不同的参数和变量而已。

每一个task最好有name属性,这个是供人读的,没有实际的操作。然后会在命令行里面输出,提示用户执行情况。
  1. 基本写法:
tasks:
  - name: make sure apache is running
    service: name=httpd state=running

当需要传入参数列表太长时,可以分隔到多行:

 tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts
            owner=root group=root mode=0644

或者用yml的字典传入参数

 tasks:
  - name: Copy ansible inventory file to client
    copy:
      src: /etc/ansible/hosts
      dest: /etc/ansible/hosts
      owner: root
      group: root
      mode: 0644
  1. 执行状态
    每个action会调用一个module,在module中会去检查当前系统状态是否需要重新执行。

    如果本次执行了,那么action会得到返回值changed;

    如果不需要执行,那么action得到返回值ok

例:

tasks:
  - name: Copy the /etc/hosts
    copy: src=/etc/hosts dest=/etc/hosts
# 第一次执行
[root@controller ~]# ansible-playbook test.yml

PLAY [test content] *******************************************************************************************************************************************************************************************

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

TASK [copy file] **********************************************************************************************************************************************************************************************
changed: [192.168.143.194]

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

# 第二次执行
[root@controller ~]# ansible-playbook test.yml

PLAY [test content] *******************************************************************************************************************************************************************************************

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

TASK [copy file] **********************************************************************************************************************************************************************************************
ok: [192.168.143.194]

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

由于第一次执行copy_hosts.yml的时候,已经拷贝过文件,那么ansible目标文件的状态避免重复执行.

2.2 Handler

主流的编程语言都会有event机制,那么handler就是playbook的event。

Handlers里面的每一个handler,也是对module的一次调用。而handlers与tasks不同,tasks会默认的按定义顺序执行每一个task,handlers则不会,它需要在tasks中被调用,才有可能被执行

Tasks中的任务都是有状态的,changed或者ok。 在Ansible中,只在task的执行状态为changed的时候,才会执行该task调用的handler,这也是handler与普通的event机制不同的地方。

应用场景:

在tasks中修改了apache的配置文件。需要重起apache。此外还安装了apache的插件。那么还需要重起apache。像这样的应该场景中,重起apache就可以设计成一个handler.


一个handler最多只执行一次:在所有的任务里表执行之后执行,如果有多个task notify同一个handler,那么只执行一次。

例:

---
- hosts: lb
  remote_user: root
  vars:
      random_number1: "{{ 10000 | random }}"
      random_number2: "{{ 10000000000 | random }}"
  tasks:
  - name: Copy the /etc/hosts to /tmp/hosts.{{ random_number1 }}
    copy: src=/etc/hosts dest=/tmp/hosts.{{ random_number1 }}
    notify:
      - call in every action
  - name: Copy the /etc/hosts to /tmp/hosts.\{\{ random_number2 \}\}
    copy: src=/etc/hosts dest=/tmp/hosts.\{\{ random_number2 \}\}
    notify:
      - call in every action

  handlers:
  - name: call in every action
    debug: msg="call in every action, but execute only one time"

输出

PLAY [test content] *******************************************************************************************************************************************************************************************

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

TASK [Copy the /etc/hosts to /tmp/hosts.7288] *****************************************************************************************************************************************************************
changed: [192.168.143.194]

TASK [Copy the /etc/hosts to /tmp/hosts.\ random_number2}}] ***************************************************************************************************************************************************
changed: [192.168.143.194]

RUNNING HANDLER [call in every action] ************************************************************************************************************************************************************************
ok: [192.168.143.194] => {
    "msg": "call in every action, but execute only one time"
}

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

3 Var

在Playbook中,通过vars关键字自定义变量,使用时用{{ }}引用以来即可。

使用方法

用户定义变量名为http_port,其值为为80。在tasks firewalld中,通过{{ http_port }}引用。

---
- hosts: web
  vars:
    http_port: 80
  remote_user: root
  tasks:
  - name: insert firewalld rule for httpd
    firewalld: port=\{\{ http_port \}\}/tcp permanent=true state=enabled immediate=yes

当变量比较多的时候,或者变量需要在多个playbook中重用的时候,可以把变量放到一个单独的文件中。通过关键字var_files把文件中定义的变量引入playbook中,使用变量的方法和在本文件中定义的变量相同。

- hosts: web
  remote_user: root
  vars_files:
      - vars/server_vars.yml
  tasks:
  - name: insert firewalld rule for httpd
    firewalld: port=\{\{ http_port \}\}/tcp permanent=true state=enabled immediate=yes

其中,vars/server_vars.yml的内容为:在这里插入代码片

http_port: 80

复杂变量

定义的语法如下

foo:
  field1: one
  field2: two

访问复杂变量中的子属性,可以利用中括号或者点号:

foo['field1']
foo.field1

陷阱:
某些时候YAML和Ansible Playbook的变量语法不能在一起好好工作了。这里仅发生在指冒号后面的值不能以{开头的时候,如果有必要以{开头,必须加上引号。总之在YAML值的定义中,如果提示YMAL语法错误,都可以尝试下加入引号来解决。

错误:

- hosts: app_servers
  vars:
      app_path: \{\{ base_path \}\}/22

修改:

- hosts: app_servers
  vars:
       app_path: "\{\{ base_path \}\}/22"

3.1 远程节点的系统变量(facts)

ansible会通过module setup来收集主机的系统信息,这些收集到的系统信息叫做facts,这些facts信息可以直接以变量的形式使用。

命令行上通过调用setup module命令可以查看可以引用的facts变量

ansible all -m setup -u root

使用方法

---
- hosts: all
  user: root
  tasks:
  - name: echo system
    shell: echo \{\{ ansible_os_family \}\}
  - name install ntp on Debian linux
    apt: name=git state=installed
    when: ansible_os_family == "Debian"
  - name install ntp on redhat linux
    yum: name=git state=present
    when: ansible_os_family == "RedHat"

3.2 文件模板中使用的变量

在playbook中定义的变量,可以直接在template中使用,同时facts变量也可以直接在template中使用,当然也包含在inventory里面定义的host和group变量。只要是在playbook中可以访问的变量,都可以在template文件中使用。

---
- hosts: web
  vars:
    http_port: 80
    defined_name: "Hello My name is Jingjng"
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest

  - name: Write the configuration file
    template: src=templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    notify:
    - restart apache

  - name: Write the default index.html file
    template: src=templates/index2.html.j2 dest=/var/www/html/index.html

  - name: ensure apache is running
    service: name=httpd state=started
  - name: insert firewalld rule for httpd
    firewalld: port=\{\{ http_port \}\}/tcp permanent=true state=enabled immediate=yes

  handlers:
    - name: restart apache
      service: name=httpd state=restarted

3.3 命令行中传递变量

定义命令行变量

在release.yml文件里,hosts和user都定义为变量,需要从命令行传递变量值。

---

- hosts: '\{\{ hosts \}\}'
  remote_user: '\{\{ user \}\}'

  tasks:
     - ...

使用命令行变量

ansible-playbook e33_var_in_command.yml --extra-vars "hosts=web user=root"

json格式传递参数:

ansible-playbook e33_var_in_command.yml --extra-vars "{'hosts':'vm-rhel7-1', 'user':'root'}"

还可以将参数放在文件里面:

ansible-playbook e33_var_in_command.yml --extra-vars "@vars.json"
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会长胖的斜杠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值