Hosts 执行的远程主机列表
Tasks 任务集
Variables 内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和 notity 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
ansible-playbook -t tagsname useradd.yml
playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
可以是如下形式:
one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
Websrvs:dbsrvs 或者,两个组的并集
Websrvs:&dbsrvs 与,两个组的交集
webservers:!phoenix 在websrvs组,但不在dbsrvs组
可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: magedu
sudo: yes 默认sudo为root
sudo_user:wang sudo为wang
play的主体部分是task list,task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出
tasks:任务列表
两种格式:
(1) action: module arguments
(2) module: arguments 建议使用
注意:shell和command模块后面跟命令,而非key=value
某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers
任务可以通过"tags“打标签,可在ansible-playbook命令上使用-t指定进行调用
示例:
tasks:
- name: disable selinux
command: /sbin/setenforce 0
如果命令或脚本的退出码不为零,可以使用如下方式替代
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors来忽略错误信息
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
---
- hosts: all
remote_user: root
tasks:
- name: install
yum: name=httpd
- name: config
copy: src=/data/playbook/httpd.conf dest=/etc/httpd/conf/
- name: service
service: name=httpd state=started enabled=yes
playbook实现二进制安装mariadb
---
- hosts: all
remote_user: root
tasks:
- name: user
user: name=mysql system=yes home=/data/mysql create_home=no shell=/sbin/nologin
- name: unarchive
unarchive: src=/data/playbook/mariadb-10.2.32-linux-x86_64.tar.gz dest=/usr/local/ owner=root group=root
- name: mysql link
file: src=/usr/local/mariadb-10.2.32-linux-x86_64 dest=/usr/local/mysql state=link
- name: mysql datadir
shell: mkdir /data/mysql
- name: mysql datadir owner group
file: path=/data/mysql owner=mysql group=mysql
- name: mysql database
shell: chdir=/usr/local/mysql/ scripts/mysql_install_db --datadir=/data/mysql --user=mysql
- name: path var
copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
- name: config
copy: src=/data/playbook/my-huge.cnf dest=/etc/my.cnf
- name: service file
shell: cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
- name: start service
shell: service mysqld start
playbook实现httpd安装,并通过copy服务触发判断是否重启服务
---
- hosts: all
remote_user: root
tasks:
- name: install
yum: name=httpd
- name: config
copy: src=/data/playbook/httpd.conf dest /etc/httpd/conf/
notify: restart httpd
- name: service
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd state=restarted
可以单独执行tags中的语句不执行其他的
---
- hosts: all
remote_user: root
tasks:
- name: install
yum: name=httpd
- name: config
copy: src=/data/playbook/httpd.conf dest=/etc/httpd/conf/
tags: conf
- name: service
service: name=httpd state=started enabled=yes
ansible-playbook -t conf httpd.yml
ansible-playbook --list-tags httpd.yml
#查看tags列表
ansible 192.168.160.150 -m setup -a 'filter=ansible_*name*'
写playbook时用{ { }}引用变量
---
- hosts: all
tasks:
- name: create file
file: name=/data/{
{
ansible_nodename}}.log state=touch
普通变量
vim /etc/ansible/hosts
[websrvs]
192.168.160.140 hostname=node1
192.168.160.150 hostname=node2
---
- hosts: all
tasks:
- name: create file
file: name=/data/{
{
hostname}}.log state=touch
公共变量
[websrvs]
192.168.160.140 hostname=node1
192.168.160.150 hostname=node2
[websrvs:vars]
suf=txt
---
- hosts: websrvs
tasks:
- name: create file
file: name=/data/{
{
hostname}}.{
{
suf}} state=touch
ansible-playbook –e hostname=file -e suf=pdf var.yml
---
- hosts: websrvs
vars:
- hostname: testfile
- suf: html
tasks:
- name: create file
file: name=/data/{
{
hostname}}.{
{
suf}} state=touch
vim var.yml
hostname: testnode
suf: yml
---
- hosts: websrvs
vars_files: var.yml
tasks:
- name: create file
file: name=/data/{
{
hostname}}.{
{
suf}} state=touch
template功能:根据模块文件动态生成对应的配置文件
template文件必须存放于templates目录下,且命名为 .j2 结尾
yaml/yml 文件需和templates目录平级,目录结构如下:
./
├── temnginx.yml
└── templates
└── nginx.conf.j2
定义端口为变量
vim templates/httpd.conf.j2
Listen {
{
httpd_port }}
在host文件里定义变量值
vim /etc/ansible/hosts
[websrvs]
192.168.160.140 httpd_port=8014
192.168.160.150 httpd_port=8015
利用template 同步httpd配置文件
---
- hosts: all
remote_user: root
tasks:
- name: install
yum: name=httpd
- name: config
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
tags: conf
- name: service
service: name=httpd state=started enabled=yes
tasks:
- name: install conf file to centos7
template: src=nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "6"
当有需要重复性执行的任务时,可以使用迭代机制
对迭代项的引用,固定变量名为”item“
要在task中使用with_items给定要迭代的元素列表
---
- hosts: websrvs
tasks:
- name: create user
user: name={
{
item }}
with_items:
- tom
- alice
- jack
- rose
多个迭代之间用字典来进行嵌套子变量
- hosts: websrvs
tasks:
- name: add some groups
group: name={
{
item }} state=present
with_items:
- group1
- group2
- group3
- name: add some users
user: name={
{
item.name }} group={
{
item.group }} state=present
with_items:
- {
name: 'user1', group: 'group1' }
- {
name: 'user2', group: 'group2' }
- {
name: 'user3', group: 'group3' }
在websrvs里生成server.conf文件,利用for循环,以ports为组生成文件内容
---
- hosts: websrvs
vars:
ports:
- 81
- 82
- 83
tasks:
- name: config
template: src=server.conf.j2 dest=/data/server.conf
{
%for port in ports %}
server {
listen {
{
port}}
}
{
%endfor%}
与上面不同的是,这次ports里面的是字典格式,所以下面格式需要写成port.listen_port
---
- hosts: websrvs
vars:
ports:
- listen_port: 81
- listen_port: 82
- listen_port: 83
tasks:
- name: config
template: src=server2.conf.j2 dest=/data/server2.conf
{
%for port in ports %}
server {
listen {
{
port.listen_port}}
}
{
%endfor%}
这里是更为复杂的多参数示例
---
- hosts: websrvs
vars:
ports:
- web1:
listen_port: 81
name: web1.li.com
dir: /data/web1
- web2:
listen_port: 82
name: web2.li.com
dir: /data/web2
- web3:
listen_port: 83
name: web3.li.com
dir: /data/web3
tasks:
- name: config
template: src=server3.conf.j2 dest=/data/server3.conf
{
%for port in ports %}
server {
listen {
{
port.listen_port}}
server_name {
{
port.name}}
root {
{
port.dir}}
}
{
%endfor%}
这里是若部分参数不一致的情况下,用if做条件判断
---
- hosts: websrvs
vars:
ports:
- web1:
listen_port: 81
# name: web1.li.com
dir: /data/web1
- web2:
listen_port: 82
name: web2.li.com
dir: /data/web2
- web3:
listen_port: 83
#name: web3.li.com
dir: /data/web3
tasks:
- name: config
template: src=server4.conf.j2 dest=/data/server4.conf
{
%for port in ports %}
server {
listen {
{
port.listen_port}}
{
%if port.name is defined %}
server_name {
{
port.name}}
{
%endif%}
root {
{
port.dir}}
}
{
%endfor%}