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  替换

posted @ 2019-07-15 16:16  言值  阅读(716)  评论(0编辑  收藏  举报