1.ansible-playbook命令行参数
[root@ansible PlayBook]# ansible-playbook -h
#ansible-playbook常用选项:
–check or -C #只检测可能会发生的改变,但不真正执行操作
–list-hosts #列出运行任务的主机
–list-tags #列出playbook文件中定义所有的tags
–list-tasks #列出playbook文件中定义的所以任务集
–limit #主机列表 只针对主机列表中的某个主机或者某个组执行
-f #指定并发数,默认为5个
-t #指定tags运行,运行某一个或者多个tags。(前提playbook中有定义tags)
-v #显示过程 -vv -vvv更详细
2.playbook系统元素
hosts、remote_user、tasks、name、 sudo_user、sudo、handlers、notify、tags、template、when、with_items
hosts
执行的远程主机列表,hosts 行的内容是一个或多个组或主机的 patterns,以逗号为分隔符。
hosts: 192.168.1.71,master,webs
remote_use
可以在hosts下,定义远程执行用户,也可以在某一个tasks中定义要执行该任务的远程用户
tasks、name
task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很清楚的辨别是属于哪一个task的,如果没有定义 name,action的值将会用作输出信息中标记特定的task。每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,(任务模块)比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行这个被定义的tasks。
sudo_user、sudo
使用sudo授权用户执行该任务
handlers、notify
事件触发动作处理,handlers、notify中的name要一致。
基础学习示例
---
- hosts: 192.168.1.31
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: config httpd
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
3.模板系统元素
for、endfor 、if、else、endif
4.变量
命令行变量
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
tasks:
- name: install pkg
yum: name={{ pkg }}
[root@ansible PlayBook]# ansible-playbook -e "pkg=httpd" variables.yml
host变量
在/etc/ansible/hosts文件中定义变量,可以针对每个主机定义不同的变量,也可以定义一个组的变量,然后直接在playbook中直接调用。注意,组中定义的变量没有单个主机中的优先级高。
[root@ansible PlayBook]# vim /etc/ansible/hosts
[apache]
192.168.1.36 webdir=/opt/test #定义单个主机的变量
192.168.1.33
[apache:vars] #定义整个组的统一变量
webdir=/web/test
[nginx]
192.168.1.3[1:2]
[nginx:vars]
webdir=/opt/web
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
tasks:
- name: create webdir
file: name={{ webdir }} state=directory #引用变量
[root@ansible PlayBook]# ansible-playbook variables.yml
playbook变量
编写playbook时,直接在里面定义变量,然后直接引用,可以定义多个变量;注意:如果在执行playbook时,又通过-e参数指定变量的值,那么会以-e参数指定的为准。
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
vars: #定义变量
pkg: nginx #变量1
dir: /tmp/test1 #变量2
tasks:
- name: install pkg
yum: name={{ pkg }} state=installed #引用变量
- name: create new dir
file: name={{ dir }} state=directory #引用变量
[root@ansible PlayBook]# ansible-playbook variables.yml
如果执行时候又重新指定了变量的值,那么会已重新指定的为准
[root@ansible PlayBook]# ansible-playbook -e "dir=/tmp/test2" variables.yml
setup模块变量
setup模块默认是获取主机信息的,有时候在playbook中需要用到,所以可以直接调用。常用的参数参考
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
tasks:
- name: create file
file: name={{ ansible_fqdn }}.log state=touch #引用setup中的ansible_fqdn
[root@ansible PlayBook]# ansible-playbook variables.yml
YAML文件变量
为了管理将所有的变量统一放在一个独立的变量YAML文件中,laybook文件直接引用文件调用变量即可。
[root@ansible PlayBook]# cat var.yml
var1: vsftpd
var2: httpd
[root@ansible PlayBook]# cat variables.yml
---
- hosts: all
remote_user: root
vars_files: #引用变量文件
- ./var.yml #指定变量文件的path(这里可以是绝对路径,也可以是相对路径)
tasks:
- name: install package
yum: name={{ var1 }} #引用变量
- name: create file
file: name=/tmp/{{ var2 }}.log state=touch #引用变量
[root@ansible PlayBook]# ansible-playbook variables.yml
5.Playbook标签
playbook文件可给任务集打标签,执行ansible-playbook通过-t选择标签执行,通过–skip-tags选择除了某个标签外的全部标签执行。
[root@ansible PlayBook]# cat httpd.yml
---
- hosts: 192.168.1.31
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=installed
tags: inhttpd
- name: start httpd
service: name=httpd state=started
tags: sthttpd
- name: restart httpd
service: name=httpd state=restarted
tags:
- rshttpd
- rs_httpd
通过-t指定tags名称,多个tags用逗号隔开
[root@ansible PlayBook]# ansible-playbook -t rshttpd httpd.yml
通过–skip-tags选项排除不执行的tags
[root@ansible PlayBook]# ansible-playbook --skip-tags inhttpd httpd.yml
6.Playbook模板
template模板提供了动态配置服务,使用jinja2语言条件判断、循环、逻辑运算、比较操作等。将template文件放在和playbook文件同级的templates目录下(需手动创建),playbook可直接引用,自动寻找模板文件,也可以通过绝对路径去指定。模板文件后缀名为.j2。
[root@ansible PlayBook]# cat testtmp.yml
---
- hosts: all
remote_user: root
vars:
- listen_port: 88 #定义变量
tasks:
- name: Install Httpd
yum: name=httpd state=installed
- name: Config Httpd
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #使用模板
notify: Restart Httpd
- name: Start Httpd
service: name=httpd state=started
handlers:
- name: Restart Httpd
service: name=httpd state=restarted
[root@ansible PlayBook]# cat templates/httpd.conf.j2 |grep ^Listen
Listen {{ listen_port }}
目录结构
[root@ansible PlayBook]# tree .
├── templates
│ └── httpd.conf.j2
└── testtmp.yml
[root@ansible PlayBook]# ansible-playbook testtmp.yml
when在template中使用
示例1
tasks:
- command: /bin/false
register: result
ignore_errors: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|success
- command: /bin/still/something_else
when: result|skipped
示例2
准备两个配置文件,一个centos6系统httpd配置文件,一个centos7系统httpd配置文件。
[root@ansible PlayBook]# tree templates/
templates/
├── httpd6.conf.j2 #6系统2.2.15版本httpd配置文件
└── httpd7.conf.j2 #7系统2.4.6版本httpd配置文件
修改playbook文件,通过setup模块获取系统版本判断。
[root@ansible PlayBook]# cat testtmp.yml
---
- hosts: all
remote_user: root
vars:
- listen_port: 88
tasks:
- name: Install Httpd
yum: name=httpd state=installed
- name: Config System6 Httpd
template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version == "6" #判断系统版本,为6便执行上面的template配置6的配置文件
notify: Restart Httpd
- name: Config System7 Httpd
template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version == "7" #判断系统版本,为7便执行上面的template配置7的配置文件
notify: Restart Httpd
- name: Start Httpd
service: name=httpd state=started
handlers:
- name: Restart Httpd
service: name=httpd state=restarted
示例3
示例4
示例5 示例6
示例7
需要目标主机上安装lsb_release软件包,来返回ansible_lsb.major_release 事件
.tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6
示例8
在playbooks 和 inventory中定义的变量都可以使用. 下面一个例子,就是基于布尔值来决定一个任务是否被执行:
vars:
epic: true
一个条件选择执行也许看起来像这样:
tasks:
- shell: echo "This certainly is epic!"
when: epic
或者像这样:
tasks:
- shell: echo "This certainly isn't epic!"
when: not epic
示例8
如果一个变量不存在,可以使用Jinja2的defined
命令跳过或略过.
tasks:
- shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
when: foo is defined
- fail: msg="Bailing out. this play requires 'bar'"
when: bar is not defined
示例9
tasks:
- command: echo {{ item }}
with_items: [ 0, 2, 4, 6, 8, 10 ]
when: item > 5
示例10
加载客户事件,调用客户自己的事件,进而把所有的模块放在任务列表顶端, 变量的返回值今后就可以访问了:
tasks:
- name: gather site specific fact data
action: site_facts
- command: /usr/bin/thingy
when: my_custom_fact_just_retrieved_from_the_remote_system == '1234'
示例11
在roles 和 includes 上面应用’when’语句
- include: tasks/sometasks.yml
when: "'reticulating splines' in output"
- hosts: webservers
roles:
- { role: debian_stock_config, when: ansible_os_family == 'Debian' }
示例11
条件导入
---
- hosts: all
remote_user: root
vars_files:
- "vars/common.yml"
- [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
tasks:
- name: make sure apache is running
service: name={{ apache }} state=running
提醒一下,很多的不同的YAML文件只是包含键和值:
cat vars/CentOS.yml
---
apache: httpd
somethingelse: 42
示例12
注册变量
‘register’ 关键词决定了把结果存储在哪个变量中.结果参数可以用在模版中,动作条目,或者 when 语句
- name: test play
hosts: all
tasks:
- shell: cat /etc/motd
register: motd_contents
- shell: echo "motd contains the word hi"
when: motd_contents.stdout.find('hi') != -1
也可以调用 “home_dirs.stdout.split()” , 也可以用其它字段切割:
- name: registered variable usage as a with_items list
hosts: all
tasks:
- name: retrieve the list of home directories
command: ls /home
register: home_dirs
- name: add home dirs to the backup spooler
file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link
with_items: home_dirs.stdout_lines
# same as with_items: home_dirs.stdout.split()
with_items在playbook中使用
with_items迭代,当有需要重复性执行的任务时,可以使用迭代机制。对迭代项的引用,固定变量名为“item”,要在task中使用with_items给定要迭代的元素列表。
示例1
[root@ansible PlayBook]# cat testwith.yml
---
- hosts: all
remote_user: root
tasks:
- name: Install Package
yum: name={{ item }} state=installed #引用item获取值
with_items: #定义with_items
- httpd
- vsftpd
- nginx
示例2
[root@ansible PlayBook]# cat testwith01.yml
---
- hosts: all
remote_user: root
tasks:
- name: Create New Group
group: name={{ item }} state=present
with_items:
- group1
- group2
- group3
- name: Create New User
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user1', group: 'group1' }
- { name: 'user2', group: 'group2' }
- { name: 'user3', group: 'group3' }
for、if在template中使用
通过使用for,if可以更加灵活的生成配置文件等需求,还可以在里面根据各种条件进行判断,然后生成不同的配置文件、或者服务器配置相关等。
示例1
[root@ansible PlayBook]# cat testfor01.yml
---
- hosts: all
remote_user: root
vars:
nginx_vhost_port:
- 81
- 82
- 83
tasks:
- name: Templage Nginx Config
template: src=nginx.conf.j2 dest=/tmp/nginx_test.conf
[root@ansible PlayBook]# cat templates/nginx.conf.j2
{% for port in nginx_vhost_port %}
server{
listen: {{ port }};
server_name: localhost;
}
{% endfor %}
示例2
[root@ansible PlayBook]# cat testfor02.yml
---
- hosts: all
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8081
server_name: "web1.example.com"
root: "/var/www/nginx/web1"
- web2:
listen: 8082
server_name: "web2.example.com"
root: "/var/www/nginx/web2"
- web3:
listen: 8083
server_name: "web3.example.com"
root: "/var/www/nginx/web3"
tasks:
- name: Templage Nginx Config
template: src=nginx.conf.j2 dest=/tmp/nginx_vhost.conf
[root@ansible PlayBook]# cat templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server{
listen: {{ vhost.listen }};
server_name: {{ vhost.server_name }};
root: {{ vhost.root }};
}
{% endfor %}
示例3
[root@ansible PlayBook]# cat testfor03.yml
---
- hosts: all
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8081
root: "/var/www/nginx/web1"
- web2:
server_name: "web2.example.com"
root: "/var/www/nginx/web2"
- web3:
listen: 8083
server_name: "web3.example.com"
root: "/var/www/nginx/web3"
tasks:
- name: Templage Nginx Config
template: src=nginx.conf.j2 dest=/tmp/nginx_vhost.conf
[root@ansible PlayBook]# cat templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server{
{% if vhost.listen is defined %}
listen: {{ vhost.listen }};
{% else %}
listen: 8888;
{% endif %}
{% if vhost.server_name is defined %}
server_name: {{ vhost.server_name }};
{% endif %}
root: {{ vhost.root }};
}
{% endfor %}
7.ignore_errors
play中只要执行命令的返回值不为0,就会报错,tasks停止,可以添加
ignore_errors: True ,忽略错误。
Ansible之Playbook详解、案例
————Blueicex 2020/2/2 12:20 blueice1980@126.com
来源:CSDN
作者:blueicex2020
链接:https://blog.csdn.net/blueicex2017/article/details/104142410