Ansible之playbook
目录
我们完成一个任务,例如安装部署一个httpd服务,我们需要多个模块(一个模块也可以称之为task)提供功能来完成。而playbook就是组织多个task的容器,他的实质就是一个文件,有着特定的组织格式,它采用的语法格式是YAML(Yet Another Markup Language)。YAML语法能够简单的表示散列表,字典等数据结构。
格式转化: www.bejson.com
ansible学习: www.ansible.com.cn/docs/playbooks_intro.html
yum makecache # 重新构建所有缓存信息
Ad-hoc 直接在命令行执行
yaml格式
字典: key: value # 键后面存在一个空格
列表:
- []
- # 代表列表, - 后面的值要加一个空格
后缀名:
- .yaml
- .yml
playbook 命令
ansible-playbook -h # 查看playbook的信息
Usage: ansible-playbook [options] playbook.yml [playbook2 ...]
-C, --check # 检查但是不会真的执行
-f FORKS, --forks=FORKS # 并发,默认是5个
--list-hosts # 列出匹配的主机
--syntax-check # 检查语法
-e # 在Playbook中引入外部参数变量
-t TAGS, --tags=TAGS # 指定执行该tags的任务
playbook
编译文件: p.yml 或 p.yaml
- hosts: web # 一个或多个主机或主机组, 以冒号分隔, 可使用通配模式
remote_user: root # 指定在被管理的主机上执行任务的用户, 默认root用户
tasks: # 任务,由模板定义的操作列表
- name: copyfile # 任务名
copy: src=/etc/fstab dest=/tmp/f # 调用模块, 执行命令
- name: createuser # 第二个任务名
user: name=alex11 # 执行第二个任务
1. Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务。
在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook 中的错误,然后重新执行即可。
Task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量,模块执行时幂等的,这意味着多次执行是安全的,因为不管执行多少次,结果永远是一样的.
2. 每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。如果没有定义name,‘action’的值将会用作输出信息中标记特定的task。
3. 定义一个task,常见的格式:”module: options” 例如:yum: name=httpd
4. ansible的自带模块中,command模块和shell模块无需使用key=value格式
传参
第一种方式
- hosts: web
tasks:
- name: create{{user}}
user: name={{user}}
命令: ansible-playbook -e user=alex13 p3.yml
第二种方式
# 编译文件: /etc/ansible/hosts, 在.yml文件中以{{user}}接收参数, 值可以不一样
[web]
10.0.0.[132:133] user=alex1 # 给主机指定变量, 传递参数
10.0.0.135 user=alex2
命令: ansible-playbook p3.yml
第三种方式
# 编译文件: /etc/ansible/hosts, 在.yml文件中以{{user}}接收参数
[web]
10.0.0.[132:133]
[web:vars] # web组名可以变化, 但[组名:vars]是固定写法
user=alex1 # 传参
命令: ansible-playbook p3.yml
第四种方式
- hosts: web
vars: # 固定写法
- user: alex # 传递参数
tasks:
- name: create{{user}}
user: name={{user}}
第五种方式
- hosts: web
tasks:
- name: yumbc
yum: name=bc
- name: sum
shell: echo 8+9|bc
register: user
- name: createuser{{user.stdout}}
user: name=alex{{user.stdout}}
# 使用register内的变量
register: user # user相当于给字典定义名字
user的结果是Python字典数据, 存储着很多信息, 包括执行时间状态变化输出等信息。
从字典中, 通过中括号[]或者 . 的方式取出想要的值.
优先级
-e 传参 > playbook文件定义vars, 传递参数 > 通过hosts文件传参
setup
# 获取系统参数
ansible 10.0.0.132 -m setup|more # playbook收集的信息
ansible 10.0.0.132 -m setup -a "filter=*processor*" # 搜索目标主机的processor信息
ansible_all_ipv4_addresses # 所有的ipv4地址
ansible_all_ipv6_addresses # 所有的ipv6的地址
ansible_bios_version # 主板bios的版本
ansible_architecture # 架构信息
ansible_date_time # 系统的时间
ansible_default_ipv4 # IPv4默认地址
- address # ip地址
- alias # 网卡名称
- broadcast # 广播地址
- gateway # 网关
- macaddress # mac地址
- netmask # 子网掩码
- network # 网段
ansible_distribution # 系统的版本
ansible_distribution_file_variety # 系统的基于对象
ansible_distribution_major_version # 系统的主版本
ansible_distribution_version # 系统的版本
ansible_domain # 系统的域
ansible_dns # 系统的dns
ansible_env # 系统的环境变量
ansible_hostname # 系统的主机名
ansible_fqdn # 系统的完整主机名
ansible_machine # 系统的架构
ansible_memory_mb # 系统的内存信息
ansible_os_family # 系统的家族
ansible_pkg_mgr # 系统的包管理工具
ansible_processor_cores # cpu的核数
ansible_processor_count # 每颗cpu上的颗数
ansible_processor_vcpus # cpu的总核数=cpu的颗数*每颗cpu上的核数
ansible_python # 系统的python版本
正则
grep "^\(.*\):.*\1$" /etc/passwd # 以什么开头, 就以什么结尾
grep -E "^(.*):.*\1$" /etc/passwd # -E, 取消正则表达式中符号的转义
\< -> # 以什么开头
\> -> # 以什么结尾
shell中: ()、{}、? # 需要转义
如:
love is love
like is like
love is not like
查询前两句的正则表达式
答案: (l..e).*\1
tags
# tags: 给此任务打标记,可单独执行标记的任务
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
copy: dest=/etc/redis.conf src=/etc/redis.conf
tags: copyfile
- name: start
service: name=redis state=started
命令: ansible-playbook -t copyfile p.yml
handlers
# handlers也是一些task的列表,和一般的task并没有什么区别。
# handlers是由通知者notify进行触发执行, 如果没有被notify, 则Handlers不会执行
# 不管有多少个通知者进行了notify,等到play中的所有task执行完成之后,handlers也只会被执行一次
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
copy: dest=/etc/redis.conf src=/etc/redis.conf
tags: copy
notify: restart
- name: start
service: name=redis state=started
handlers:
- name: restart
service: name=redis state=restarted
命令: ansible-playbook -t copy p.yml # 当执行copy文件,notify触发执行handlers,执行restart
template
# Jinja是基于Python的模板引擎。template类是Jinja的另一个重要组件,可以看作一个编译过的模块文件,用来生产目标文本,传递Python的变量给模板去替换模板中的标记。
# template可以使用变量来接收远程主机上setup收集到的facts信息, 针对不同配置的主机, 定制配置文件。用法大致与copy模块相同。
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
template: dest=/etc/redis.conf src=/etc/redis.conf
tags: copy
notify: restart
- name: start
service: name=redis state=started
handlers:
- name: restart
service: name=redis state=restarted
修改 /etc/redis.conf: bind {{ansible_default_ipv4.address}} # redis监听本地地址
命令: ansible-playbook -t copy p.yml
# 本地的目录下创建一个templates目录,将redis.conf配置文件copy到templates目录中, 就可以用相对路径
- hosts: web
tasks:
- name: install
yum: name=redis
- name: copyfile
template: dest=/etc/redis.conf src=redis.conf
tags: copy
notify: restart
- name: start
service: name=redis state=started
handlers:
- name: restart
service: name=redis state=restarted
when
# when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行(跳过)
- hosts: web
tasks:
- name: file
copy: content="大弦嘈嘈如急雨" dest=/opt/file
when: ansible_distribution_major_version=="7"
- name: file
copy: content="小弦切切如私语" dest=/opt/file
when: ansible_distribution_major_version=="6"
- hosts: web
tasks:
- name: file
copy: content="大弦嘈嘈如急雨\n" dest=/opt/file
when: sum=="7"
- name: file
copy: content="小弦切切如私语\n" dest=/opt/file
when: sum=="6"
命令: ansible-playbook -e sum=7 p11.yml # 通过自己传值的方式
with_items
循环
# 当有需要重复性执行的任务时,可以使用迭代机制简化代码
@1、对迭代变量的引用,固定变量名:item
@2、要在tasks中使用with_items给定要迭代的元素列表
@3、列表格式:字符串、字典
- hosts: web
tasks:
- name: createuser
user: name={{item}}
with_items:
- alex1
- alex2
- hosts: web
tasks:
- name: creategroup
group: name={{item}}
with_items:
- wusir1
- wusir2
- name: file
user: name={{item}}
with_items:
- alex1
- alex2
嵌套循环
- hosts: web
tasks:
- name: creategroup
group: name={{item}}
with_items:
- wusir1
- wusir2
- name: file
user: name={{item.name}} group={{item.group}}
with_items:
- {"name":alex1,"group":wusir1}
- {"name":alex2,"group":wusir2}
# 这里定义的就是一个字典键值对,注意字典的写法,"key":'value' 值要带引号
vim操作
u 撤销
p 粘贴
yy 复制n行
d$ 从当前位置删除
o 当前位置下面增加空白行,并切换到编辑模式
r 替换