1.1 配置eprl源
yum install epel-release
1.2 yum安装ansible
yum install ansible
1.3 加入被控端IP
vim /etc/ansible/hosts #在该文件中加入IP
1.4 配置控制主机ssh秘钥
ssh-keygen -t rsa
一路回车即可在$HOME/.ssh目录下生成id_rsa和id_rsa.put私钥和公钥两个文件。
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.200
ssh-copy-id命令会自动将id_rsa.pub文件的内容追加到远程主机root用户下.ssh/authorized_keys文件中。
1.5 修改配置文件
vim /etc/ansible/ansible.cfg
host_key_checking = False
log_path = /var/log/ansible.log
[accelerate]
#accelerate_port = 5099
accelerate_port = 10000
#accelerate_timeout = 30
#accelerate_connect_timeout = 5.0
# If set to yes, accelerate_multi_key will allow multiple
# private keys to be uploaded to it, though each user must
# have access to the system via SSH to add a new key. The default
# is "no".
accelerate_multi_key = yes
批量执行ping命令
ansible all -m ping
2.1.1 ansible命令集
/usr/bin/ansible Ansibe AD-Hoc 临时命令执行工具,常用于临时命令的执行
/usr/bin/ansible-doc Ansible 模块功能查看工具
/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块 的官网平台,基于网络的
/usr/bin/ansible-playbook Ansible 定制自动化的任务集编排工具
/usr/bin/ansible-pull Ansible远程执行命令的工具,拉取配置而非推送配置(使用较少,海量机器时使用,对运维的架构能力要求较高)
/usr/bin/ansible-vault Ansible 文件加密工具
/usr/bin/ansible-console Ansible基于Linux Consoble界面可与用户交互的命令执行工具
其中比较常用的是/usr/bin/ansible 和 /usr/bin/ansible-playbook
2.1.2 ansible-doc命令
ansible-doc 命令常用于获取模块信息及其使用帮助,一般用法如下:
ansible-doc -l #获取全部模块的信息
ansible-doc -s MOD_NAME #获取指定模块的使用帮助
ansible-doc全部命令
[root@server ~]# ansible-doc
Usage: ansible-doc [options] [module...]
Options:
-h, --help show this help message and exit # 显示命令参数API文档
-l, --list List available modules #列出可用的模块
-M MODULE_PATH, --module-path=MODULE_PATH #指定模块的路径
specify path(s) to module library (default=None)
-s, --snippet Show playbook snippet for specified module(s) #显示playbook制定模块的用法
-v, --verbose verbose mode (-vvv for more, -vvvv to enable # 显示ansible-doc的版本号查看模块列表:
connection debugging)
--version show program's version number and exit
查看mysql信息
[root@yusy-test yusy]# ansible-doc -l |grep mysql
azure_rm_mysqlfirewallrule_info Get Azure MySQL Firewall Rule facts
azure_rm_mysqlconfiguration_info Get Azure MySQL Configuration facts
mysql_info Gather information about MySQL servers
mysql_db Add or remove MySQL databases from a remote host
azure_rm_mysqlserver_info Get Azure MySQL Server facts
azure_rm_mysqldatabase_info Get Azure MySQL Database facts
mysql_variables Manage MySQL global variables
mysql_user Adds or removes a user from a MySQL database
proxysql_backend_servers Adds or removes mysql hosts from proxysql admin interface
azure_rm_mysqlconfiguration Manage Configuration instance
azure_rm_mysqlfirewallrule Manage MySQL firewall rule instance
azure_rm_mysqlserver Manage MySQL Server instance
mysql_replication Manage MySQL replication
proxysql_mysql_users Adds or removes mysql users from proxysql admin interface
azure_rm_mysqldatabase Manage MySQL Database instance
mysql-user
[root@yusy-test yusy]# ansible-doc -s mysql_user
- name: Adds or removes a user from a MySQL database
mysql_user:
append_privs: # Append the privileges defined by priv to the existing ones for this user instead of overwriting existing ones.
ca_cert: # The path to a Certificate Authority (CA) certificate. This option, if used, must specify the same certificate as used by the server.
check_implicit_admin: # Check if mysql allows login as root/nopassword before trying supplied credentials.
client_cert: # The path to a client public key certificate.
client_key: # The path to the client private key.
config_file: # Specify a config file from which user and password are to be read.
connect_timeout: # The connection timeout when connecting to the MySQL server.
encrypted: # Indicate that the 'password' field is a `mysql_native_password` hash.
host: # The 'host' part of the MySQL username.
host_all: # Override the host option, making ansible apply changes to all hostnames for a given user. This option cannot be used when creating users.
login_host: # Host running the database.
login_password: # The password used to authenticate with.
login_port: # Port of the MySQL server. Requires `login_host' be defined as other than localhost if login_port is used.
login_unix_socket: # The path to a Unix domain socket for local connections.
login_user: # The username used to authenticate with.
name: # (required) Name of the user (role) to add or remove.
password: # Set the user's password..
priv: # MySQL privileges string in the format: `db.table:priv1,priv2'. Multiple privileges can be specified by separating each one using a forward slash:
`db.table:priv/db.table:priv'. The format is based on MySQL `GRANT' statement. Database and table names can be quoted, MySQL-style. If column
privileges are used, the `priv1,priv2' part must be exactly as returned by a `SHOW GRANT' statement. If not followed, the module will always
report changes. It includes grouping columns by permission (`SELECT(col1,col2') instead of `SELECT(col1',SELECT(col2))).
sql_log_bin: # Whether binary logging should be enabled or disabled for the connection.
state: # Whether the user should exist. When `absent', removes the user.
update_password: # `always' will update passwords if they differ. `on_create' will only set the password for newly created users.
2.1.3 ansible命令详解
命令的具体格式如下:
ansible -pattern> [-f forks] [-m module_name] [-a args]
也可以通过ansible -h来查看帮助,常用的选项意义如下:
2.2.1 主机连通性测试
使用以下命令进行主机连通性测试
ansible web -m ping
2.2.2 command模块
这个模块可以直接在远程主机上执行命令,并将结果返回本主机,如:
ansible web -m command -a 'ss -ntl'
ansible web -m command -a 'ls -a /home/work'
command模块接受命令名称,后面是空格分隔的列表参数。给定的命令将在所有选定的节点上执行。它不会通过shell进行处理,比如$HOME和操作如"<",">","|",";","&" 工作(需要使用(shell)模块实现这些功能)。注意,该命令不支持| 管道命令。
该模块常用的几个命令为
chdir # 在执行命令之前,先切换到该目录
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form # 要执行的Linux指令,一般使用Ansible的-a参数代替。
creates # 一个文件名,当这个文件存在,则该命令不执行,可以用来做判断
removes # 一个文件名,这个文件不存在,则该命令不执行
命令示例如下:
ansible web -m command -a 'chdir=/data/ ls' #先切换到/data/ 目录,再执行“ls”命令
ansible web -m command -a 'creates=/data/aaa.jpg ls' #如果/data/aaa.jpg存在,则不执行“ls”命令
ansible web -m command -a 'removes=/data/aaa.jpg cat /data/a' #如果/data/aaa.jpg存在,则执行“cat /data/a”命令
2.2.3 shell模块
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等。只要是shell命令,都可以通过这个模块在远程主机上运行。
如:
ansible web -m shell -a 'cat /etc/passwd |grep "keer"'
2.2.4 copy模块
这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。
其相关选项如下:
src #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content #用于替换"src",可以直接指定文件的值
dest #必选项,将源文件复制到的远程主机的绝对路径
backup #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode #递归设定目录的权限,默认为系统默认权限
force #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others #所有的 file 模块中的选项可以在这里使用
用法举例如下:
ansible web -m copy -a 'src=~/hello dest=/data/hello'
ansible web -m copy -a 'content="I am keer\n" dest=/data/name mode=666'
ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'
2.2.5 file模块
该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。
下面是一些常见的命令:
force #需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group #定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner #定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径
recurse #递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest #被链接到的路径,只应用于state=link的情况
state #状态,有以下选项:
ansible web -m file -a 'path=/data/app state=directory'
ansible web -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'
ansible web -m file -a 'path=/data/bbb.jpg state=absent'
2.5.6 fetch 模块
该模块用于从远程某主机获取(复制)文件到本地。
有两个选项
举例如下:
ansible web -m fetch -a 'src=/data/hello dest=/data'
文件保存的路径在我们设置的接收目录下的被管制主机ip目录下
2.5.7 cron模块
该模块适用于管理cron计划任务的。其使用的语法和crontab文件中的语法一致,同时,可以指定以下选项:
举例如下:
ansible web -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'
ansible web -m shell -a 'crontab -l'
ansible web -m cron -a 'name="ntp update every 5min"minute=*/5 jbo="/sbin/ntpdate 172.17.0.1 & >/dev/null" state=absent'
2.5.8 yum 模块
该模块主要用于软件的安装
其选项如下:
name= #所安装的包的名称
state= #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache #强制更新yum的缓存
conf_file #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check #是否禁止GPG checking,只用于presentor latest。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
示例:
ansible web -m yum -a 'name=htop state=present'
2.5.9 service模块
该模块用于服务程序的管理。
其主要选项如下:
arguments #命令行提供额外的参数
enabled #设置开机启动。
name= #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置
ansible web -m service -a 'name=nginx state=started enable=true'
ansible web -m servuce -a 'name=nginx state=stopped'
2.5.10 user模块
该模块主要是用来管理用户账号。
其主要选项如下:
comment # 用户的描述信息
createhome # 是否创建家目录
force # 在使用state=absent时, 行为与userdel –force一致.
group # 指定基本组
groups # 指定附加组,如果指定为(groups=)表示删除所有组
home # 指定用户家目录
move_home # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name # 指定用户名
non_unique # 该选项允许改变非唯一的用户ID值
password # 指定用户密码
remove # 在使用state=absent时, 行为是与userdel –remove一致
shell # 指定默认shell
state # 设置帐号状态,不指定为创建,指定值为absent表示删除
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid # 指定用户的uid
举例如下:
ansible web -m user -a 'name=yusy uid=11111'
ansible web -m user -a 'name=yusy state=absent'
2.5.11 group 模块
该模块主要用于添加或删除组。
常用的选项如下:
ansible web -m group -a 'name=yusy gid=111'
ansible web -m group -a 'name=yusy state=absent'
2.5.12 script 模块
该模块用于将本机的脚本在被管理端的机器上运行
该模块直接制定脚本的路径即可,具体使用方法如下:
vim /tmp/df.sh
ansible web -m script -a '/tmp/df.sh'
2.5.13 setup 模块
该模块主要用于收集信息,是通过调用facts组件来实现的。
facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。
ansible web -m setup -a 'filter="*mem*"'
setup模块还有一个很好用的功能就是可以保存所筛选的信息至主机上,同时,文件名为被管制的主机的IP,这样方便知道是哪台机器出的问题。
示例如下:
ansible web -m setup -a 'filter="*mem*"' --tree /tmp/facts
Playbook与ad-hoc相比,是一种完全不同的运用ansible的方式。类似于saltstack的state状态文件。ad-hoc无法持久使用,playbook可以持久使用。
Playbook是由一个或多个play组成的列表,play的主要功能在于将事先归并为一组的主机装扮成通过ansible中的task定义好的角色。从根本上来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务。
ansible-playbook采用YAML语法编写,后缀可以使yaml,也可以是yml
示例:
---
- hosts: control-node # 将要执行任务的主机,已经在hosts文件中定义好了,可以是单个主机或主机组
remote_user: root # 在目标主机上执行任务时的用户身份
vars: #定义变量
- pkg: httpd #变量
tasks: #定义一个任务的开始
- name: "install httpd package." #定义任务的名称
yum: name={{ pkg }} state=installed #调用模块,具体要做的事情
- name: "copy httpd configure file to remote host."
copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: #定义执行一个动作(action)让handlers来引用执行,与handlers配合使用。当这个任务执行状态发生改变时,触发handlers执行.
- restart httpd #执行的动作,这里必须与handlers中的name定义内容一致
- name: "boot httpd service."
service: name=httpd state=started
handlers: # handlers与tasks是同一级别。处理器:task中notify定义的action出发执行相应的处理动作
- name: restart httpd #要与notify定义的内容相同
service: name=httpd state=restarted #触发要执行的动作
3.3.1 playbook语法有如下特性:
3.3.2 执行playbook
第一次执行可以加-c选项,检查写的playbook是否正确
ansible-playbook -c yaml/httpd.yaml
通过ansible-playbook命令运行
格式:ansible-playbook
#ansible-playbook常用选项:
3.5.1 主机与用户
在一个playbook开始时,最先定义的是要操作的主机和用户
---
- hosts: 192.168.1.31
remote_user: root
除了上面的定义外,还可以在某一个tasks中定义要执行该任务的远程用户
tasks:
- name: run df -h
remote_user: test
shell: name=df -h
还可以定义使用速度授权用户执行该任务
tasks:
- name: run df -h
sudo_user: test
sudo: yes
shell: name=df -h
3.5.2 tasks任务列表
每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很清楚的辨别是属于哪一个task的,如果没有定义name,action的值将会用作输出信息中标记特定的task。
每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,(任务模块)比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行这个被定义的tasks。
tasks:
- name: create new file
file: path=/tmp/test01.txt state=touch
- name: create new user
user: name=test001 state=present
3.5.3 Handlers与Notify
很多时候当一个配置发生改变,则需要重启服务,(比如httpd配置文件发生改变了),这时候就可以用到handlers和notify了。
当发生改动时,notify actions会在playbook的每一个task结束时被触发,而且及时有多个不同task通知改动的发生,notify actions 只会被触发一次。比如多个resources指出因为一个配置文件被改动,所以Apache需要重启,但是重新启动的操作只会被执行一次。
用于安装httpd并配置启动
---
- 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
#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。
3.6 playbook中变量的使用
3.6.1 yaml文件中定义变量
编写playbook时,直接在里面定义变量,然后直接引用,可以定义多个变量;注意:如果在执行playbook时,又通过-e参数指定变量的值,那么会以-e参数指定的为准。
---
- hosts: compute-node
remote_user: root
vars:
pkg: httpd # 定义变量
tasks:
- name: install httpd service
yum: name={{ pkg }} state=installed # 引用变量
playbook中用vars关键字声明变量,变量定义-- 变量名:变量值
变量引用:{{变量名}}
3.6.2 引用外部变量
在命令行使用 --extra-vars参数赋值变量
执行playbook的时候通过参数-e(或者–extra_vars)传入变量,这样传入的变量在整个playbook中都可以被调用,属于全局变量
[root@LOCALHOST ~]# ansible-playbook yaml/extra_vars.yaml --extra-vars "filename=temp.txt"
[root@ansible PlayBook]# ansible-playbook -e "pkg=httpd" variables.yml
–extra-vars “变量名=变量值”
3.6.3 资产清单(inverntory)中定义的变量
资产清单(/etc/ansible/hosts)
[root@LOCALHOST ~]# cat /etc/ansible/hosts
[load-node]
openstack-load1
openstack-load2
[compute-node]
openstack-compute1 ansible_ssh_host=10.0.1.10 ansible_ssh_port=2002 ansible_ssh_user=stanley ansible_ssh_pass=etyfhzmweadf
openstack-compute2
[control-node]
openstack-control1 filename=control1.txt # 主机变量
openstack-control2 filename=control2.txt
[openstack:children]
load-node
compute-node
control-node
[openstack:vars]
issue="Hello, World" # 组变量
注意:组变量定义时,不要落下关键字vars,[组名:vars]。 在playbook中引用{{ 变量名 }}即可。
ansible内置了一些固定的主机变量名,在inventory中定义其值,如下:
3.6.4 直接使用facts变量
setup模块默认是获取主机信息的,有时候在playbook中需要用到,所以可以直接调用。
[root@LOCALHOST ~]# cat yaml/facts_vars.yaml
---
- hosts: compute-node
remote_user: root
tasks:
- name: write fqdn into fqdn.log
shell: "echo {{ ansible_fqdn }} {{ ansible_eth1.ipv4.address }} > /tmp/fqdn.log"
上述代码中{{ansible_fqdn}}就是直接引用的facts变量;
{{ansible_eht1.ipv4.address}}引用的值就相当于下面这样:
{ "ansible_eth1": {
"ipv4": {
"address":10.0.1.10,
}, }, }
3.6.5 注册变量
在playbook中用register关键字定义一个变量,这个变量的值就是当前任务执行的输出结果。
[root@LOCALHOST ~]# cat yaml/reg_vars.yaml
---
- hosts: load-node
remote_user: root
tasks:
- name: show date
shell: "/bin/date"
register: date # 注册一个变量
- name: Record time log
shell: "echo {{ date.stdout }} > /tmp/date.log"
引用的注册变量要用{{date.stdout}}表示标准输出
[root@openstack-load1 ~]# cat /tmp/date.log
2018年 03月 29日 星期四 15:52:01 CST
如果直接{{ date }} 这样引用,则文件中写入的是如下内容
{stderr_lines: [], uchanged: True, uend: u2018-03-29 15:49:52.609894, failed: False, ustdout: u2018\u5e74 03\u6708 29\u65e5 \u661f\u671f\u56db 15:49:52 CST, ucmd: u/bin/date, urc: 0, ustart: u2018-03-29 15:49:52.602918, ustderr: u, udelta: u0:00:00.006976, stdout_lines: [u2018\u5e74 03\u6708 29\u65e5 \u661f\u671f\u56db 15:49:52 CST]}
3.6.6YAML文件中定义独立的变量
为了方便将所有的变量统一放在一个独立的变量YAML文件中,playbook文件直接引用文件调用变量即可。
# 定义存放变量的文件
[root@ansible PlayBook]# cat var.yml
var1: vsftpd
var2: httpd
# 编写playbook
[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 #引用变量
执行playbook
[root@ansible PlayBook]# ansible-playbook variables.yml
3.6.7 变量优先级
上述这些变量定义的方法,他们的优先级如下:
在
一个playbook文件中,执行时如果想执行某一个任务,那么可以给每个任务集进行打标签,这样在执行的时候可以通过-t选择指定标签执行,还可以通过–skip-tags选择除了某个标签外全部执行等。
编辑playbook
[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
# 正常执行的结果
[root@ansible PlayBook]# ansible-playbook httpd.yml
PLAY [192.168.1.31] **************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.1.31]
TASK [install httpd] *************************************************************************************************************************
ok: [192.168.1.31]
TASK [start httpd] ***************************************************************************************************************************
ok: [192.168.1.31]
TASK [restart httpd] *************************************************************************************************************************
changed: [192.168.1.31]
PLAY RECAP ***********************************************************************************************************************************
192.168.1.31 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# 通过-t指定tags名称,多个tags用逗号隔开
[root@ansible PlayBook]# ansible-playbook -t rshttpd httpd.yml
PLAY [192.168.1.31] **************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.1.31]
TASK [restart httpd] *************************************************************************************************************************
changed: [192.168.1.31]
PLAY RECAP ***********************************************************************************************************************************
192.168.1.31 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@ansible PlayBook]# ansible-playbook --skip-tags inhttpd httpd.yml
PLAY [192.168.1.31] **************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.1.31]
TASK [start httpd] ***************************************************************************************************************************
ok: [192.168.1.31]
TASK [restart httpd] *************************************************************************************************************************
changed: [192.168.1.31]
PLAY RECAP ***********************************************************************************************************************************
192.168.1.31 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
3.8.1 when 条件判断
当关键字when后面的条件满足时(也就是通过运算得到的结果为true时),才会执行当前任务。
示例如下:
---
- hosts: load-node,img
remote_user: root
tasks:
- name: "touch flag file"
command: "touch /tmp/this_is_{{ ansible_distribution }}_system"
when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == '6') or
(ansible_distribution == "Debian" and ansible_distribution_major_version == '7')
上述代码中,ansible_distribution和ansible_distribution_major_version都是是Facts变量,分别表示Linux发行版和版本号
3.8.2 循环语句
playbook中的循环类型,如下表:
列表中前三个为常用的循环语句
---
- name: when and with_items
hosts: load-node
remote_user: root
gather_facts: false
tasks:
- name: Create thress groups
group: name=testgroup6 state=present
ignore_errors: yes
register: excu_result
- name: Append excu_result to tmp.txt
shell: "echo {{ excu_result }} > /tmp/tmp.txt"
- name: Create some users
user: name={{ item }} group=testgroup6 state=present
when: excu_result|success
with_items:
- testuser1
- testuser2
- testuser3
释义:
gather_facts: false表示运行此playbook时不收集目标主机的系统信息。因为默认此项是开启的,每次运行playbook都会收集主机facts,这会影响playbook的运行速度。将gather_facts设为false即可关闭。
when:excu_result|success的意思为当变量excu_result执行结果为成功状态,则执行当前的任务。其中success为Ansible内部过滤器方法,返回True代表命令运行成功。还有excu_result|failed表示excu_result执行结果为失败状态;excu_result|skipped表示excu_result执行被跳过。
with_items的值还可以写成[testuser1, testuser2, testuser3]
输出用户的姓名和电话:
---
1. hosts: load-node
remote_user: root
tasks:
2. name: print phone records
debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.phone }})"
with_dict: {'alice':{'name':'Alice Appleworth', 'phone':'13243252136'}, 'bob':{'name':'Bob Banarama', 'phone': '18766761211'}}
playbook中对字典的循环,与python中对字典循环类似,取值方法也一样
[root@LOCALHOST ~]# cat yaml/with_fileglob.yaml
---
- hosts: DH-TEST
remote_user: root
gather_facts: false
tasks:
- name: create a directory
file: path=/root/script state=directory
ignore_errors: yes
register: result
- name: copy some scripts
copy: src={{ item }} dest=/root/script owner=root mode=600
when: result|success
with_fileglob:
- /root/sh/*
with——fileglob匹配单个目录中的素有文件,非递归匹配模式
3.9.1 ignore_errors
在有些情况下,一些必需运行的命令或脚本会报一些错误,而这些错误并不一定真的说明有问题,但是经常会给接下来要运行的任务造成困扰,甚至直接导致playbook运行中断。
这时候我们可以在相关任务中添加ignore_errors:true来屏蔽当前任务的报错信息。ansible也将视该任务运行成功,不在报错,这样就不会对接下来要运行的任务造成额外困扰。但是要注意的是,我们不应孤独依赖ignore_errors,因为他会隐藏所有的报错信息,而应该把精力集中在寻找报错的原因上面,这样才能从根本上解决问题。
示例如下:
[root@LOCALHOST ~]# cat yaml/httpd.yaml
---
- hosts: load-node
remote_user: root
vars:
- pkg: httpd
tasks:
- name: "install httpd package."
yum: name={{ pkg }} state=installed
- name: "copy httpd configure file to remote host."
copy: src=/root/config/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
ignore_errors: true # 忽略错误
- name: "start httpd service."
tags:
- start_httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
3.9.2 failed_when
当满足一定的条件时,主动抛出错误
[root@LOCALHOST ~]# cat yaml/failed_when.yaml
---
- hosts: DH-TEST
remote_user: root
gather_facts: false
tasks:
- name: get process
shell: ps aux | wc -l
register: process_count
failed_when: process_count > 3
- name: touch a file
file: path=/tmp/test3.txt state=touch owner=root mode=070
failed_when: process_count >3 当进程数大于3时主动抛出错误,后续任务就不会执行了。如果不满足条件,则不会抛出错误。
3.9.3 changed_when
[root@LOCALHOST ~]# cat yaml/changed_when.yaml
---
- hosts: DH-TEST
remote_user: root
gather_facts: false
tasks:
- name: touch a file
file: path=/tmp/changed_test state=touch
执行结果:
如果想要关闭状态改变的提示,则可以添加changed_when: false,如下:
[root@LOCALHOST ~]# cat yaml/changed_when.yaml
---
- hosts: DH-TEST
remote_user: root
gather_facts: false
tasks:
- name: touch a file
file: path=/tmp/changed_testi2 state=touch
changed_when: false # 关闭状态改变提示
Roles是一种在大型Playbook中使用的剧本配置模式,它有着自己特定的结构。用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
剧本roles设计思路:将公共任务、资源、变量等对象尽可能独立。
一个roles的案例如下所示:
site.yml # 主入口文件
webservers.yml # webserver类型服务所用的剧本
dbservers.yml # 数据库类型的服务所用的剧本
files/ # 存放通用的将要被上传的文件
templates/ # 存放通用的模板文件
roles/ # roles目录名称是固定的
common/ # 此目录下的各个组件是所有角色共用的
tasks/ # 存放通用的任务文件
handlers/ # 存放通用的处理器文件
vars/ # 存放通用的变量文件
meta/ # 存放通用的角色依赖文件
webservers/ # 存放webserver类型的服务的各个组件
files/ # 存放webserver角色需要的上传文件
templates/ # 存放webserver角色需要的模板文件
tasks/
handlers/
vars/
meta/
而在playbook中,可以这样使用roles:
---
- hosts: webservers
roles:
- common
- webservers
也可以向roles传递参数,例如:
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'"
3.10.1 创建role的步骤
3.10.2 role内个目录中可用的文件
Ansible Galaxy是ansible官方Roles分享平台(galaxy.ansible.com),在Galaxy平台上所有人可以免费上传或下载Roles,在这里好的技巧、思想、架构得以积累和传播。
3.11.1 ansible-galaxy命令用法
[root@LOCALHOST tasks]# ansible-galaxy --help
Usage: ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
Options:
-h, --help 列出此帮助信息并退出
-c, --ignore-certs 忽略SSL证书验证错误。
-s API_SERVER, --server=API_SERVER 指定API目的服务器
-v, --verbose 详情模式,(-vvv获取更多,-vvvv启用连接检测)
--version 显示项目版本信息并退出
ansible-galaxy search lamp
ansible-galaxy install vivaserver.lamp
ansible-galaxy search zabbix --author dj-wasabi
其中dj-wasabi是作者的用户名
3.11.2批量安装多个roles
# cat roles.txt
user1.role1,v1.0.0
user2.role2,v0.5
user2.role3
安装
ansible-galaxy install -r roles.txt
参考
https://www.cnblogs.com/keerya/p/7987886.html
https://www.jianshu.com/p/171578692c94
https://www.cnblogs.com/yanjieli/p/10969299.html