ansible04-ansible-playbook

playbook文件示例

执行playbook,拷贝服务配置文件到目标主机后,对原文件修改后再次执行playbook,已启动的服务不会再次重启

- hosts: host10
  remote_user: root
  tasks:
    - name: install httpd
      yum: name=httpd state=present
    - name: copy configure file
      copy: src=files/httpd.conf dest=/etc/httpd.conf                  # src为相对路径,相对于当前用户家目录
    - name: start service
      service: name=httpd state=started enabled=yes

playbook的命令行相关选项

运行playbook
ansible-palybook  xxx.yml

--limit
限制只有host主机组中的10.100主机执行命令
ansible-playbook file.yml --limit 192.168.10.100

--check
建议运行playbook之前先检查
ansible-playbook file.yml --check

--list-host
列出该playbook影响到的主机
ansible-playbook file.yml --list-host

--list-tasks
列出该playbook中的任务列表,tasks的name
ansible-playbook file.yml --list-tasks

--list-tags
列出该playbook中tags列表
ansible-playbook file.yml --list-tags

|| /bin/true
如果命令或脚本的退出不为零,可以使用如下方式替代

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true

ignore_errors: true
或者使用ignore_errors来忽略错误信息

tasks:
  - name: run this command and ingore the result
    shell: /usr/bin/somecommand
    ingore_errors: true

playbook字段

handlers

说明:
1.用于当某资源发生变化时,执行一定操作,相当于触发器,例如:当配置文件发生变化后,重启服务
2.其本质还是tasks,与tasks同级

使用方法:
1.首先在tasks中定义notify,指定handlers的名字
2.在playbook中与tasks平级的地方定义handlers,指定名字和动作,名字要和notify中定义的一致

notify

可用于在每个play的最后被触发,在notify中定义的tasks称为handler

- host: host10
  remote_user: root

  tasks:
    - name: install httpd
      yum: name=httpd state=present
    - name: copy configure file
      copy: src=files/httpd.conf dest=/etc/httpd.conf
      notify:
        - restart service
        - check progress    # 指定触发条件,即谁发生了改变,与触发器名称保持一致
    - name: start service
      service: name=httpd state=started enabled=yes

  handlers:    # 指定触发器
    - name: restart service
      service: name=httpd state=restarted      # 指定触发器动作
    - name: check progress
      shell: killall -0 httpd > /tmp/httpd.log    # 0信号不对进程做任何干预,仅仅是确定该进程是否存在
                                                  # 因此往往被用于集群服务中确认某一服务是否正常运行

killall -0 nginx
echo $?                      # 若返回0,则nginx进程正常运行,若返回1,则nginx服务已停止

tags
将动作打上标签,通过ansible-playbook -t 指定要运行的标签,这样可以增playbook的灵活性

cat httpd.yml

- host: host10
  remote_user: root

  tasks:
    - name: install httpd
      yum: name=httpd state=present
      tags: httpd
    - name: copy configure file
      copy: src=files/httpd.conf dests=/etc/httpd.conf
      notify: restart service
      tags: httpd
    - name: start service
      service: name=httpd state=started enabled=yes
      tags:httpd

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

# -t   指定标签,多个动作用逗号间隔
# 允许多个动作指定为同一个标签,标签都会执行
ansible-playbook -t httpd httpd.yml

when
根据实际情况的不同,执行不同的逻辑,例如:实现不同OS拷贝不同的配置文件

ls /root/ansible-playbook/templates/

nginx6.conf.j2
nginx7.conf.j2

cat /root/ansible-playbook/test-template.yml

- host: all
  remote_user: root

  tasks:
    - name: install package
      yum: name=nginx state=present
    - name: copy config file to cent6
      template: src=nginx6.conf.j2 dest=/etc/nginx/nginx.conf
    - name: copy config file to cent7
      template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service
      when: {{ ansible_distribution_major_version }} == "7"              # 变量来自setup模块
    - name: start service
      service: name=nginx state=started enabled=yes
      notify: restart service
      when: {{ ansible_distribution_major_version }} == "6"
  handlers:
    - name: restart service
      service: name=nginx state=restarted

templates
作用:
用于自定义修改配置文件,在tasks中定义template,指定src和dest,template中的配置项会应用到目标配置文件中

说明:
1.使用jinja2语言,该模块只能用于playbook
2.根据模块文件动态生成对应的配置文件
3.template文件必须存放于templates目录中,且命名以.j2结尾
4.yml/yaml文件与templates目录平级

例子,将nginx 的进程数设置为cpu核心数

vim nginx.conf
...
worker_processes  auto;                                   # 修改nginx的进程数量,与cpu核心数一致,配置文件在不同机器上生效时,nginx的进程数会与cpu核心数一致
...

cp nginx.conf /root/ansible-palybook/templates/nginx.conf.j2

cat /root/ansible-playbook/test-template.yml
- host: host10
  remote_user: root
  tasks:
    - name: install package
      yum: name=nginx
    - name: copy config file
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf             # 文件在templates目录中,直接指定
    - name: start service
      service: name=nginx state=started enabled=yes

另一个例子,将nginx的进程数设置为cpu核心数的两倍

vim nginx.conf
...
worker_processes {{ ansible_processor_vcpus*2 }};                      # 该变量来源于setup模块,ansible host10 -m setup -a 'filter=*cpu*'
...

cp nginx.conf /root/ansible-palybook/templates/nginx.conf.j2

cat /root/ansible-playbook/test-template.yml
- host: host10
  remote_user: root
  tasks:
    - name: install package
      yum: name=nginx
    - name: copy config file
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service                                     # 配置文件发生改变,重启服务
    - name: start service
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart service
      service: name=nginx state=restarted                              

with_items迭代列表

适用于输出多个命令,安装多个软件包,拷贝多个文件的情况

例如,创建多个用户组

- hosts: host10
  remote_user: root
  tasks:
    - name: create user
      group: name={{ item }} state=present
      with_items:
        - group1
        - group2
        - group3

迭代嵌套子变量

---
- hosts: host10
  remote_user: root
  tasks:
    - name: create groups
      group: name={{ item }} state=present
      with_items:
        - group1
        - group2
        - group3
    - name: create users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: "user1", group: "group1" }
        - { name: "user2", group: "group2" }
        - { name: "user3", group: "group3" }

playbook中的for循环

定义一个playbook
cat for.yml
---
- hosts: all
  remote_user: root
  vars:
    ports:               # 指定变量ports,变量中存放的是列表[81, 82, 83]
      - 81
      - 82
      - 83
  tasks:
    - name: copy config file
      template: src=for.conf.j2 dest=/etc/for.conf

配置模板文件
cat /root/ansible-playbook/templates/for.conf.j2

{% for port in ports %}           # 此处的变量ports对应yml文件中的变量
server{
    listen  {{ port }}
}
{% endfor %}


文件输出如下
cat /etc/for.conf

server{
    listen  81
}
server{
    listen  82
}
server{
    listen  83
}

上述例子中的端口也可以用字典表示

cat for2.yml
---
- hosts: all
  remote_user: root
  vars:
    ports:               # 指定变量ports,变量中存放的是列表,列表的每项是字典[{listen_port: 81}, {listen_port: 82}, {listen_port: 83}]
      - listen_port: 81
      - listen_port: 82
      - listen_port: 83
  tasks:
    - name: copy config file
      template: src=for2.conf.j2 dest=/etc/for2.conf


配置模板文件
cat /root/ansible-playbook/templates/for2.conf.j2

{% for port in ports %}
server{
    listen  {{ port.listen_port }}
}
{% endfor %}

更为灵活的写法

cat for3.yml
---
- hosts: host10
  remote_user: root
  vars:
    hosts_vars:
      - web1:
        port: 81
        name: web1.com
        rootdir: /data/web1
      - web2:
        port: 82
        name: web2.com
        rootdir: /data/web2
      - web3:
        port: 83
        name: web1.com
        rootdir: /data/web3

  tasks:
    - name: copy file
      template: src=for3.conf.j2 dest=/tmp/for3.conf

配置模板文件
cat /root/ansible-playbook/templates/for3.conf.j2

{% for i in hosts_vars %}
server{
    listen  {{ i.port }}
    servername  {{ i.name }}
    documentroot  {{ i.rootdir }}
}
{% endfor %}

在for循环中嵌套if判断

cat for4.yml
---
- hosts: host10
  remote_user: root
  vars:
    hosts_vars:
      - web1:                            # 相比较上面的例子,此处没有指定web1的name
        port: 81
        rootdir: /data/web1
      - web2:                            # 相比较上面的例子,此处没有指定web2的rootdir
        port: 82
        name: web2.com
      - web3:
        port: 83
        name: web3.com
        rootdir: /data/web3

  tasks:
    - name: copy file
      template: src=for4.conf.j2 dest=/tmp/for4.conf

配置模板文件
cat /root/ansible-playbook/templates/for4.conf.j2

{% for i in hosts_vars %}
server{
    listen  {{ i.port }}
{% if i.name is defined %}
    servername  {{ i.name }}
{% endif %}
{% if i.rootdir is defined %}
    documentroot  {{ i.rootdir }}
{% endif %}
}
{% endfor %}
posted @   立勋  阅读(11)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示