ansible详解
介绍:
ansible是一种IT自动化工具,它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署、滚动更新等。ansible适用于管理企业IT基础设施,从具有少数主机的小规模到数千个实例的企业环境,ansible也是一种简单的自动化语言,可以完美的描述IT应用程序基础架构。
特点:
易读的描述语言,无需特殊编码技能,任务会按顺序执行。
可以做到应用部署,配置管理,工作流程安排。
无代理架构,使用openSSH通信,没有代理维护成本。
安装:
yum安装:yum -y install ansible
rpm安装:http://www.rpmfind.net/linux/rpm2html/search.php?query=ansible下载rpm包后使用rpm -ivh ***.rpm 命令安装即可
当前安装的版本为2.9.16
架构介绍:
INVENTORY(主机清单):管理被管理机器的域名或者地址,配置文件hosts
MODULES(模块):在ansible中有很多不同的模块,例如copy、file、yum、user、git。。。
主机清单配置:
一。主机清单配置有三种配置方式
1. 未分组的主机,没有在分组内的主机信息
192.168.100.10 or www.baidu.com
2. 分组内的主机
[组名]
101.133.235.54 ansible_ssh_user=root ansible_ssh_pass=root用户密码 key=value # ansible_ssh_user=root 含义是以root用户登录被管理的主机, ansible_ssh_user和ansible_ssh_pass也可以不用配置 ,调用参数中加上也可以,密码的话可以配置免密登录。key=value:可以在这里配置单独主机的变量信息
3. 如果配置的机器有关联性,也可以配置为如下格式
[组名]
www[001:006].example.com 前闭后闭区间
二。在主机清单中也可以配置组内的变量
[组名:vars]
key=value
key1=value2
...
变量:
变量除了可以在主机清单中配置组变量和单主机变量也可以单独在其他文件中配置,如下
mkdir /etc/ansible/group_vars && cd /etc/ansible/group_vars
vim 组名.yml
---
server_name: node
http_port: 80
这个变量文件是组变量,并且格式为yml格式
变量引用的格式为{{key}},例如
ansible 组名 -m shell -a 'echo {{key}}'
yml格式说明:
1. 缩进表示层级关系
2. 不支持制表符“tab”缩进,使用空格缩进
3. 通常开头缩进2个空格
4. 字符后缩进1个空格,如冒号,逗号等。
5. ”---“ 表示YAML格式,一个文件的开始
6. “#”表示注释
ansible.cfg配置文件详解
inventory = /etc/ansible/hosts ##主机清单位置
forks = 5 ##多进程运行
become = root
remote_port = 22
host_key_checking = False ##是否进行主机连接检查
timeout = 10 ##超时时间
log_path = /var/log/ansible.log ##日志目录
private_key_file = /root/.ssh/id_rsa ##密钥位置
ansible的ad-hoc命令详解
--ask-vault-pass ansible加密模块,一般搭配ansible-vault命令使用,会要求输入密码
--list-hosts 展示所有的主机清单配置信息
--syntax-check ansible-playbook命令的时候进行文档语法检查使用
--vault-id VAULT_IDS ansible加密模块,一般搭配ansible-vault命令使用
--vault-password-file ansible加密模块,一般搭配ansible-vault命令使用,把密码存储在一个文件中,可以使用这个命令运行加过密的yaml文件
--version 显示当前ansible的版本号,配置文件的位置,已配置的模块搜索路径,模块位置,可执行位置和退出
-B SECONDS, 后台运行超时时间,异步运行
-C, --check 运行检查,不执行任何操作
-D, --diff 展示文件之间的差异
-M MODULE_PATH, 执行的模块路径,默认为~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
-P POLL_INTERVAL, 设置轮询间隔。如果使用了-B 则默认为15秒
-a MODULE_ARGS, 模块参数
-e EXTRA_VARS, 传递参数 key=value
-f FORKS, 并行数,默认为5
-h, --help 帮助文档信息
-i INVENTORY, 主机清单位置
-l SUBSET, 进一步限制所选主机/组模式 --limit=192.168.91.135 只对这个ip执行
-m MODULE_NAME 指定模块名,默认为command,可选为shell、copy、file、yum、user、git、service、setup
-o, --one-line 压缩输出,摘要输出.尝试一切都在一行上输出
-t TREE, --tree TREE 将日志输出到此目录
-v, --verbose 更详细的展示信息 (-vvv 展示的信息更多, -vvvv 启动debug模式进行展示)
提权的相关参数,控制目标主机是以什么用户执行
--become-method 提权方法,默认是以sudo进行
--become-user 在目标主机上是以什么用户执行,默认以root用户
-K, --ask-become-pass 用户对象的密码
-b, --become 表示会在目标主机上进行提权操作
连接选项:控制谁连接主机和如何连接
--private-key 密钥文件位置,
-T TIMEOUT, 连接超时时间,会覆盖配置文件配置的超时时间
-c CONNECTION, 连接类型,默认为smart
-k, --ask-pass 请求连接密码,可以配置在主机清单中,一般情况下都会配置免密登录
-u REMOTE_USER, 连接用户,默认为None
示例:
ansible 组名 -m shell -a 'echo "这是一个ansible创建的新文件" > /tmp/1.txt' -u user -b --become-user root -K
ansible 组名 --list-hosts
有时编写的playbook文件中会存在重要信息,考虑到安全,可以使用此工具进行加密!
ansible-vault命令详解:
create 创建一个加密后的文件,可以是yaml文件,也可以是普通文件
encrypt 加密一个yaml文件
encrypt_string 加密一个字符串
rekey 修改一个加密文件的密钥
decrypt 解密一个yaml文件
edit 编辑加密文件
view 查看加密文件
--version 显示程序的版本号,配置文件的位置,已配置的模块搜索路径,模块位置,可执行位置和退出
-h, --help 展示帮助文档
-v, --verbose 更详细的展示信息 (-vvv 展示的信息更多, -vvvv 启动debug模式进行展示)
示例:
1. ansible-vault create hello.yml
2. ansible-vault encrypt hello.yml
3. ansible-vault decrypt hello.yml
4. ansible-vault view hello.yml
5. ansible-vault edit hello.yml
6. ansible-vault rekey hello.yml
7. 使用encrypt_string加密字符串时,先使用ansible-vault encrypt_string 字符串并且输入密码把加密后的铭文生成,然后拷贝到指定的yaml文件中,最后在运行playbook剧本的时候使用
--ask-vault-pass或者--valut--password-file命令正确执行剧本文件。
ansible常用模块:
shell:
示例:ansible 组名 -m shell -a 'echo "this is test txt" >> /tmp/2.txt' -u root
copy:
把本地文件拷贝到目标主机上指定的目录
src:当前主机的文件
dest:目标主机指定的目录
示例:ansible 组名 -m copy -a "src=ansible.txt dest=/tmp" -u root
file:
在目标主机上创建一个文件或者目录
dest:在目标主机创建的文件或者目录
mode:文件的权限
state:操作的状态,状态值都有directory:创建目录、link:创建软连接、hard:创建硬连接、touch:创建一个空文件、absent:删除文件
示例:ansible 组名 -m file -a "dest=/tmp/ansible2.txt mode=600 state=directory" -u root
yum:
在目标主机上安装一个软件
state:操作状态,状态值都有present:安装任意版本的软件、latest:安装最新版本的软件、absent:删除安装的软件
name:安装的软件名,可以带上版本号
示例:ansible 组名 -m yum -a "name=mysql state=latest" -u root
user:
在目标主机上创建一个用户
name:创建的用户名称
state:absent:删除用户
group:设置用户属组
password:用户的密码
示例:
ansible 组名 -m user -a "name=hbase password=hbase" -u root
ansible 组名 -m user -a "name=hbase state=absent" -u root
ansible 组名 -m user -a "name hadoop password=hadoop shell=/sbin/nologin" -u root
git:
在目标主机上通过git拉取项目源码
repo:git的地址
dest:在目标主机上存放的位置
示例:ansible 组名 -m git -a "repo=https://gitee.com/lwr_dgas/AnsibleUI.git dest=/tmp/ansible" -u root
service:
管理目标主机的服务的启动,停止,重启,以及开机启动等信息
name:服务名
state :started :启动、stopped:停止、restarted:开机启动、reloaded:重新加载
enable:true:开机启动、false :开机不启动
示例:ansible 组名 -m service -a "name=nginx state=started enabled=true" -u root
setup:
收集目标主机的详细信息
示例:
ansible 组名 -m setup -u root
ansible 组名 -m setup -a "filter=ansible_*_mb" :对目标主机的详细信息进行过滤
常用信息
ansible_all_ipv4_addresses:仅显示ipv4的信息。
ansible_devices:仅显示磁盘设备信息。
ansible_distribution:显示是什么系统,例:centos,suse等。
ansible_distribution_major_version:显示是系统主版本。
ansible_distribution_version:仅显示系统版本。
ansible_machine:显示系统类型,例:32位,还是64位。
ansible_eth0:仅显示eth0的信息。
ansible_hostname:仅显示主机名。
ansible_kernel:仅显示内核版本。
ansible_lvm:显示lvm相关信息。
ansible_memtotal_mb:显示系统总内存。
ansible_memfree_mb:显示可用系统内存。
ansible_memory_mb:详细显示内存情况。
ansible_swaptotal_mb:显示总的swap内存。
ansible_swapfree_mb:显示swap内存的可用内存。
ansible_mounts:显示系统磁盘挂载情况。
ansible_processor:显示cpu个数(具体显示每个cpu的型号)。
ansible_processor_vcpus:显示cpu个数(只显示总的个数)。
yum_repository:
增加yum源信息
name:相当于.repo文件定义中括号的[仓库ID]
description:相当于.repo文件中的name
baseurl:相当于.repo文件中baseurl
gpgcheck:相当于.repo文件中gpgcheck
enabled:相当于.repo文件中enabled
file:相当于.repo文件的名称,不使用时默认以name加.repo命令
gpgcakey:前提是gpgcheck=yes,相当于.repo文件中gpgkey,验证gpg公钥
state: present|absent:默认present,absent表示删除
示例:
ansible all -m yum_repository -a 'name=aliepel baseurl=https://mirrors.aliyun.com/epel/7/x86_64/ enabled=yes gpgcheck=yes gpgcakey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-7 state=present file=AlicloudEpel'
ansible all -m yum_repository -a 'file=AlicloudEpel name=aliepel state=absent'
get_url:
下载文件
url:下载的地址
owner:指定属主
group:指定属组
mode:指定权限
force : 如果yes,dest不是目录,将每次下载文件,如果内容改变,替换文件。如果否,则只有在目标不存在时才会下载该文件。
dest:下载下来的位置
示例:
ansible 组名 -m get_url -a "url=...... dest=/tmp" -u root
unarchive:
解压文件
src:待解压的文件路径
dest:解压后保存的目录
copy:默认为yes,当copy=yes,那么拷贝的文件是从ansible主机复制到远程主机上的,如果设置为copy=no,那么会在远程主机上寻找src源文件
mode:设置解压缩后的文件权限
示例:
ansible 组名 -m unarchive -a "src=./nginx.tar.gz dest=/tmp copy=no" -u root
playbook
示例:
---
- hosts: 组名
gather_facts: no ##默认情况下playbook会收集目标主机的详细信息,no的话是关闭收集主机的详细信息
remote_user: root ## 使用什么账户
vars:
var_name: value ##当前playbook全局的变量名
tasks:
- name: add repo
yum_repository:
name: nginx
description: nginx repo
baseurl: http://nginx.org/packages/centos/7/$basearch/
gpgcheck: no
enabled: 1
- name: install nginx
yum:
name: nginx
state: latest
- name: copy nginx configuration file
copy:
src: ./site.conf
dest: /etc/nginx/conf.d/site.conf
- name: start nginx
service:
name: nginx
state: started
- name: create nginx html directory
file:
dest: /var/www/html
state: directory
- name: create nginx index.html
shell:
echo "hello {{var_name}}" >/var/www/html/index.html
#site.conf
server {
listen 80;
server_name www.qywang.com;
location / {
root /var/www/html;
index index.html;
}
}
1. ansible-playbook yml文件名 --syntax-check进行文档格式的检查
2. ansible-playbook yml文件名 直接运行
handlers:在变更时执行操作,当一个任务执行后,如果执行成功则可以触发另一个任务
示例:
---
- hosts: 组名
gather_facts: no
remote_user: root
vars:
var_key: var_value
tasks:
- name: copy nginx configuration file
copy:
src: ./site.conf
dest: /tmp/site.conf
notify:
- reload nginx
handlers:
- name: restart nginx
service:
name: nginx
state: reloaded
当copy任务执行完成,并且对目标地址有修改时,会唤醒任务名叫reload nginx的任务,并且这个任务在handlers中。
tags:对不同的任务打上不同的标签,可以在执行这个playbook的时候选择执行具体的任务
示例:
---
- hosts: 组名
gather_facts: no
remote_user: root
vars:
var_key: var_value
tasks:
- name: copy txt
copy:
src: ./test.txt
dest: /tmp/test.txt
tags: copy
- name: install mysql
yum:
name: mysql
state: present
tags: instll
执行命令的两种方式
ansible-playbook main.yml --tags “copy,install” or 只执行标签为copy和install的任务
ansible-playbook main.yml --tags “copy” or 只执行标签为copy的任务
ansible-playbook main.yml --skip-tags “copy” 跳过标签为copy执行其他的任务
playbook文件调试:对于playbook文件在执行过程中,需要用到的一些参数信息,我们可以通过调试的方式打印出来,以验证正确性
示例:
---
- hosts: 组名
gather_facts: no
remote_user: root
vars:
var_key: var_value
tasks:
- name: debug
debug:
msg: {{var_key}}
debug:
msg: {{group_names}}
ansible-playbook命令详解:
--ask-vault-pass ansible加密模块,一般搭配ansible-vault命令使用
--flush-cache clear the fact cache for every host in inventory
--force-handlers run handlers even if a task fails
--list-hosts 展示当前剧本的所有主机信息
--list-tags 展示当前剧本的所有标签信息
--list-tasks 展示当前剧本的所有任务信息
--skip-tags 在执行剧本的时候跳过指定的标签
--start-at-task START_AT_TASK
start the playbook at the task matching this name
--step one-step-at-a-time: confirm each task before running
--syntax-check 当前剧本检查,不运行剧本
--vault-id VAULT_IDS ansible加密模块,一般搭配ansible-vault命令使用
--vault-password-file ansible加密模块,一般搭配ansible-vault命令使用
--version 显示当前ansible的版本号,配置文件的位置,已配置的模块搜索路径,模块位置,可执行位置和退出
-C, --check 运行检查,不执行任何操作
-D, --diff 展示文件之间的差异
-M MODULE_PATH, --module-path MODULE_PATH 执行的模块路径,默认为~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
-e EXTRA_VARS, --extra-vars EXTRA_VARS : 传递参数 key=value
-f FORKS, --forks FORKS 并行数,默认为5
-h, --help 帮助文档信息
-i INVENTORY, 主机清单位置
-l SUBSET, --limit SUBSET 进一步限制所选主机/组模式 --limit=192.168.91.135 只对这个ip执行
-t TAGS, --tags TAGS 在运行剧本的时候如果加上这个参数,只运行指定的task
-v, --verbose 更详细的展示信息 (-vvv 展示的信息更多, -vvvv 启动debug模式进行展示)
提权的相关参数,控制目标主机是以什么用户执行
--become-method 提权方法,默认是以sudo进行
--become-user 在目标主机上是以什么用户执行,默认以root用户
-K, --ask-become-pass 用户对象的密码
-b, --become 表示会在目标主机上进行提权操作
连接选项:控制谁连接主机和如何连接
--private-key 密钥文件位置,
-T TIMEOUT, 连接超时时间,会覆盖配置文件配置的超时时间
-c CONNECTION, 连接类型,默认为smart
-k, --ask-pass 请求连接密码,可以配置在主机清单中,一般情况下都会配置免密登录
-u REMOTE_USER, 连接用户,默认为None
注册变量:
示例:
---
- hosts: 组名
gather_facts: no
remote_user: root
vars:
var_key: var_value
tasks:
- name: register var
shell: date + "%F_%T"
register: datetime
- name: touch file
file:
dest: /tmp/r_{{datetime.stdout}}
state: touch
ansible-playbook main.yaml
如以上的main.yaml剧本文件中的datetime变量。
include & import 区别
include_tasks(动态):在运行时导入
1. --list-tags.--list-tasks 不会显示到输出
2. 不能使用notify触发来自include*内处理程序名称。
import_tasks(静态):在playbook剧本文件解析时预先导入
1. 不能与循环一起使用
2. 将变量用于目标文件或者角色名称时,不能使用inventory(主机、主机组等)中的变量。
怎么选择使用呢?
import_tasks导入的话应该是在长任务进行拆分的时候使用,
include_tasks的话应该在处理不同的工作流程并根据一些动态收集的数据做出决策。
条件
在ansible中条件判断的话主要有三个关键字 when 、and、or ,示例如下
main.yaml
---
- hosts: 组名
gather_facts: no
remote_user: root
vars:
var_key: var_value
tasks:
- name: install nginx
yum:
name: nginx
state: present
when:
- ansible_distribution == "CentOs"
- ansible_distribution_major_version =="6"
when:
- (ansible_distribution == "CentOs" and ansible_distribution_major_version =="6") or
- (ansible_distribution == "RedHat" and ansible_distribution_major_version =="7")
...
循环
with_list: 每个嵌套在大列表都被当做一个整体存放在item变量中,不会“拉平”嵌套的列表,只会循环的处理列表(最外层)中的每一项
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_list: [1,2,3]
结果:
ok: [101.133.235.54] => (item=1) => {
"msg": 1
}
ok: [101.133.235.54] => (item=2) => {
"msg": 2
}
ok: [101.133.235.54] => (item=3) => {
"msg": 3
}
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_list:
- 6
- 5
- 4
结果:
ok: [101.133.235.54] => (item=6) => {
"msg": 6
}
ok: [101.133.235.54] => (item=5) => {
"msg": 5
}
ok: [101.133.235.54] => (item=4) => {
"msg": 4
}
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item.test1}}"
with_list:
- {test1: a,test2: b}
- {test1: c,test2: d}
结果:
ok: [101.133.235.54] => (item={u'test1': u'a', u'test2': u'b'}) => {
"msg": "a"
}
ok: [101.133.235.54] => (item={u'test1': u'c', u'test2': u'd'}) => {
"msg": "c"
}
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_list:
- [1,2,3]
- [a,b]
结果为:
ok: [101.133.235.54] => (item=[1, 2, 3]) => {
"msg": [
1,
2,
3
]
}
ok: [101.133.235.54] => (item=[u'a', u'b']) => {
"msg": [
"a",
"b"
]
}
with_items: “拉平”嵌套的列表,将小列表展开后一并将小列表中的元素循环输出
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_items: [1,2,3]
结果:
ok: [101.133.235.54] => (item=1) => {
"msg": 1
}
ok: [101.133.235.54] => (item=2) => {
"msg": 2
}
ok: [101.133.235.54] => (item=3) => {
"msg": 3
}
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_list:
- 6
- 5
- 4
结果:
ok: [101.133.235.54] => (item=6) => {
"msg": 6
}
ok: [101.133.235.54] => (item=5) => {
"msg": 5
}
ok: [101.133.235.54] => (item=4) => {
"msg": 4
}
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item.test1}}"
with_items:
- {test1: a,test2: b}
- {test1: c,test2: d}
结果:
ok: [101.133.235.54] => (item={u'test1': u'a', u'test2': u'b'}) => {
"msg": "a"
}
ok: [101.133.235.54] => (item={u'test1': u'c', u'test2': u'd'}) => {
"msg": "c"
}
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_list:
- [1,2,3]
- [a,b]
结果为:
ok: [101.133.235.54] => (item=1) => {
"msg": 1
}
ok: [101.133.235.54] => (item=2) => {
"msg": 2
}
ok: [101.133.235.54] => (item=3) => {
"msg": 3
}
ok: [101.133.235.54] => (item=a) => {
"msg": "a"
}
ok: [101.133.235.54] => (item=b) => {
"msg": "b"
}
with_together:将列表中的元素“对其合并”
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_together:
- [1,2,3]
- [a,b,c]
结果为:
ok: [101.133.235.54] => (item=[1, u'a']) => {
"msg": [
1,
"a"
]
}
ok: [101.133.235.54] => (item=[2, u'b']) => {
"msg": [
2,
"b"
]
}
ok: [101.133.235.54] => (item=[3, u'c']) => {
"msg": [
3,
"c"
]
}
with_cartesian:将每个小列表中的元素按照“笛卡尔的方式”组合后,循环处理每个组合
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_cartesian:
- [1,2,3]
- [test1,test2]
结果为:
ok: [101.133.235.54] => (item=[1, u'test1']) => {
"msg": [
1,
"test1"
]
}
ok: [101.133.235.54] => (item=[1, u'test2']) => {
"msg": [
1,
"test2"
]
}
ok: [101.133.235.54] => (item=[2, u'test1']) => {
"msg": [
2,
"test1"
]
}
ok: [101.133.235.54] => (item=[2, u'test2']) => {
"msg": [
2,
"test2"
]
}
ok: [101.133.235.54] => (item=[3, u'test1']) => {
"msg": [
3,
"test1"
]
}
ok: [101.133.235.54] => (item=[3, u'test2']) => {
"msg": [
3,
"test2"
]
}
with_indexed_items:处理列表中每一项时,按照顺序为为每一项添加编号,会将嵌套的两层列表“拉平”,多层嵌套时,不会完全“拉平”
---
- hosts: webserver
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{ item.0 }}-{{item.1}}"
with_indexed_items:
- test1
- test2
- test3
结果为:
ok: [101.133.235.54] => (item=[0, u'test1']) => {
"msg": "0-test1"
}
ok: [101.133.235.54] => (item=[1, u'test2']) => {
"msg": "1-test2"
}
ok: [101.133.235.54] => (item=[2, u'test3']) => {
"msg": "2-test3"
}
---
- hosts: webserver
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "index is : {{ item.0 }} , value is {{ item.1 }}"
with_indexed_items:
- [ test1, test2 ]
- [ test3, test4, test5 ]
- [ test6, test7 ]
结果为:
ok: [101.133.235.54] => (item=[0, u'test1']) => {
"msg": "index is : 0 , value is test1"
}
ok: [101.133.235.54] => (item=[1, u'test2']) => {
"msg": "index is : 1 , value is test2"
}
ok: [101.133.235.54] => (item=[2, u'test3']) => {
"msg": "index is : 2 , value is test3"
}
ok: [101.133.235.54] => (item=[3, u'test4']) => {
"msg": "index is : 3 , value is test4"
}
ok: [101.133.235.54] => (item=[4, u'test5']) => {
"msg": "index is : 4 , value is test5"
}
ok: [101.133.235.54] => (item=[5, u'test6']) => {
"msg": "index is : 5 , value is test6"
}
ok: [101.133.235.54] => (item=[6, u'test7']) => {
"msg": "index is : 6 , value is test7"
}
with_sequence:按照顺序生成数字序列,还能格式化数据,与c语言printf类似
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_sequence: start=1 end=5 stride=2 format="number is %0.2f"
结果为:
ok: [101.133.235.54] => (item=number is 1.00) => {
"msg": "number is 1.00"
}
ok: [101.133.235.54] => (item=number is 3.00) => {
"msg": "number is 3.00"
}
ok: [101.133.235.54] => (item=number is 5.00) => {
"msg": "number is 5.00"
}
with_random_choice:从列表中随机返回一个值
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
key: [1,2,3]
tasks:
- name: test loop
debug:
msg: "{{item}}"
with_random_choice:
- 1
- 2
- 3
结果为:
ok: [101.133.235.54] => (item=3) => {
"msg": 3
}
jinja2模板
语法
{%set list=['one','two','three']%}
{%for i in list%}
{{i}}
{%endfor%}
{%set list=['one','two','three']%}
{%for i in list%}
{%if i =='two' %}
-> 2
{%elif i== 'three' %}
->3
{%endif%}
{%endfor%}
{% set dict={'zhangsan':26,'lisi':25}%}
{% for key,value in dict.iteritems() %}
{{key}} ->{{value}}
{% endfor%}
template:
template模块和前面说的copy功能类似,但是template模块可以解析jinja2模板,所以通常和jinja2模板组合使用,示例:
---
- hosts: webserver
gather_facts: no
remote_user: root
vars:
var_key: var_value
tasks:
- name: copy nginx configuration file
template:
src: site.conf.j2
dest: /etc/nginx/conf.d/...
...
roles:
当我们在配置playbook时会发现它会越来越庞大,所有的tasks,handles,templates等任务或文件都写在一个yml文件中,这样在修改中难免会浪费时间,显得缺乏条理性.而roles的出现刚好解决了这一问题.
roles的特点 : 目录结构清晰.在使用roles的时候,我们会将不同的任务放在不同的目录下,结构一目了然,在修改的过程中也更方便寻找.可以相互调用.在roles中,所有的任务和文件都可以自由调用,通过import或include方法,可以将要执行的任务导入一个文件中,使roles在实现playbook功能的情况下更有条理性.下边是roles目录下安装nginx的目录结构 :
nginx/
├── files 存放静态的文件
│ └── fstab
├── handlers 存放需要触发的任务,里面必须main.yml文件
│ └── main.yml
├── tasks 存放的执行的任务 ,里面必须main.yml文件
│ ├── copyfile.yml
│ ├── install.yml
│ ├── main.yml
│ └── start.yml
├── templates 存放的模板文件
│ ├── centos6.conf
│ └── nginx.conf
└── vars 存放的是参数,里面必须main.yml文件
└── main.yml
从上图中可以看出handles,tasks,vars文件需要用main.yml文件来触发任务,而且针对Contos的不同版本做了相应的判断,所有任务一目了然.
roles入口文件设置
当我们把roles中所有的任务都配置好以后,最后就需要在roles同级的目录下设置入口文件.入口文件的设置最好以任务名命名,方便识别.例如上边的例子中入口文件可以命名为nginx.yml,下边是文件中的内容,重点在于roles下指定nginx目录
---
- hosts: web
remote_user: root
roles:
- nginx
roles的执行顺序
- 先查找当前目录下roles目录里面指定的对应文件夹
- 找tasks目录下面的main.yml文件,如果import_tasks 就导入
- 如果遇到了templates,去找templates文件夹下面的对应文件
- 如果遇到了notify,去找handlers里面的main.yml文件
- 如果遇到了copy,去找files里面的对应文件
- 如果看到了变量,如果是setup收集的变量就去setup,如果不是就去vars里面的main.yml文件查找