bingmous

欢迎交流,不吝赐教~

导航

Ansible学习笔记

相关资料

官网:https://www.ansible.com/
官方文档:https://docs.ansible.com/
官方文档:https://docs.ansible.com/ansible/2.9/index.html
官方Galaxy参考:http://galaxy.ansible.com
Ansible写的比较不错的博客:https://www.zsythink.net/archives/category/运维相关/ansible
Ansible中文权威指南:http://ansible.com.cn/
GitHub:https://github.com/ansible/ansible
GitHub的一些最佳实践:https://github.com/ansible/ansible-examples

使用总结

  • ansible --version,查看版本、配置文件目录、模块目录等信息
  • ansible -hansible-playbook -h,查看使用帮助,
  • ansible-doc [模块],查看模块详细使用,-l列出所有模块,-s简要显示
  • 基本用法ansible [主机清单] -m [模块] -a ['参数'],默认模块是command,command模块在执行一些命令时,一些脚本中使用的符号会有问题,比如$、>,使用shell模块时,用一些复杂命令也有可能失败,可以写到一个脚本中,执行这个脚本,注意要写!#/bin/bash,否则可能执行失败,使用模块为script
## 主机清单配置:
# 需要首先将被控制的主机放入/etc/ansible/hosts,或使用-i指定主机清单如 -i hosts1,hosts2

## 修改配置文件:/etc/ansible/ansible.cfg
#host_key_checking = False # 取消注释,即时没ssh的主机,通过密码也可以连接
#log_path = /var/log/ansible.log # 取消注释,指定日志文件

# 加速ssh访问 修改 /etc/ssh/sshd_config配置UseDNS no

-k	# 指定远程密码,默认是root用户远程,会使用一个密码登录所有主机,当密码不一样时就有问题了,而且#host_key_checking = False 默认为true,即使密码相同,也必须使用ssh连接过。因此,一般使用基于key的验证,先对所有主机做免密登录,`ssh-keygen`,`ssh-copy-id`。
-u	# 指定用哪个用户登录,默认使用root
-a	# 使用模块要指定的参数 用''或"",一般用'',执行shell时""可能不生效

## 使用举例:
ansible all -a 'creates=/opt ls /'	# 所有主机执行,creates表示文件存在就不执行
ansible all -m shell -a "ls -l /"
ansible all -m shell -a 'hostname'
ansible all -m copy -a 'src=/opt/ansible_test/f.txt dest=/opt'
ansible all -m script -a './1.sh'
ansible all -m fetch -a 'src=/var/log/messages dest=/opt/data'
# 注意,命令中的参数最好使用单引号

## 常用模块:
shell	# 执行shell命令
script	# 执行脚本,自动拷贝脚本过去然后执行
copy	# 拷贝模块,从本机拷贝到被控服务器
fetch	# 从被控服务器抓取文件到当前主机
archeive	# 打包模块
unarcheive	# 解压模块

## playbook 运行
ansible-playbook xxx.yml -t tag1,tag2

## 需要的playbook可以先在galaxy上搜索下参考

介绍

运维自动化发展历程及技术应用:

  • IaaS:基础设施即服务,提供基础服务器环境,比如虚拟机
  • PaaS:平台即服务,提供平台,可以在上面开发自己的应用
  • SaaS:软件即服务,提供软件,可以直接用

自动化运维应用场景:文件传输,应用部署,配置管理,任务流编排

常用自动化运维工具:

  • Ansible(Python,agentless,中小型应用环境)
  • Saltstatck(Python,一般需要部署agent,执行效率高)
  • Puppet(ruby,功能强大,配置复杂,重型,适合大型环境)
  • Fabric(python,agentless)
  • Chef(ruby国内应用少),Cfenging,func

Ansible特性:

  • 模块化,调用特定模块(或者叫插件),完成特定任务
  • 有paramike(实现远程控制,基于ssh,agentless),pyYaml(实现剧本),jinja2(模板语言)三个关键模块
  • 支持自定义模块
  • 基于python实现
  • 部署简单,基于python和ssh,agentless
  • 安全,基于openssh
  • 支持playbook编排任务
  • 幂等性,一个任务执行1遍与n遍效果一样,不会因为重复执行带来意外情况
  • 可以使用任何编程语言编写模块
  • yaml格式,编排任务,支持丰富的数据结构
  • 较强大的多层解决方案,roles

总结工作模式:

  • 单一模块(单一命令)
  • playbook(复杂任务的组合)
  • roles(更复杂,一个playbook搞不定)

Ansible架构:

ansible的作用以及工作结构
1、ansible简介:
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。

主要包括:
    (1)、连接插件connection plugins:负责和被监控端实现通信;
    (2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
    (3)、各种模块核心模块、command模块、自定义模块;
    (4)、借助于插件完成记录日志邮件等功能;
    (5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

2、ansible的架构:连接其他主机默认使用ssh协议

Ansible主要组成部分:

  • ANSIBLE PLAYBOOKS:任务剧本(任务集),编排任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件
  • INVENTORY:Ansible管理主机的清单  /etc/anaible/hosts
  • MODULES: Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
  • PLUGINS: 模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
  • API:供第三方程序调用的应用程序编程接口
  • ANSIBLE: 组合INVENTORY、API、MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具
Ansible命令执行来源:
    1> USER,普通用户,即SYSTEM ADMINISTRATOR
    2> CMDB(配置管理数据库) API 调用
    3> PUBLIC/PRIVATE CLOUD API调用  (公有私有云的API接口调用)
    4> USER-> Ansible Playbook -> Ansibile

利用ansible实现管理的方式:
    1> Ad-Hoc 即ansible单条命令,主要用于临时命令使用场景
    2> Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

Ansible-playbook(剧本)执行过程
    将已有编排好的任务集写入Ansible-Playbook
    通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行

Ansible主要操作对象
   HOSTS主机
   NETWORKING网络设备

注意事项:
   执行ansible的主机一般称为主控端,中控,master或堡垒机
   主控端Python版本需要2.6或以上
   被控端Python版本小于2.4需要安装python-simplejson
   被控端如开启SELinux需要安装libselinux-python
   windows不能做为主控端
   ansible不是服务,不会一直启动,只是需要的时候启动

Ansible安装

# rpm包安装: EPEL源
    yum install http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
    yum install ansible

# 编译安装:
    yum -y install python-jinja2 PyYAML python-paramiko python-babel
    python-crypto
    tar xf ansible-1.5.4.tar.gz
    cd ansible-1.5.4
    python setup.py build
    python setup.py install
    mkdir /etc/ansible
    cp -r examples/* /etc/ansible


# Git方式:
    git clone git://github.com/ansible/ansible.git --recursive
    cd ./ansible
    source ./hacking/env-setup

# pip安装: pip是安装Python包的管理器,类似yum
    yum install python-pip python-devel
    yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
    pip install --upgrade pip
    pip install ansible --upgrade

# 确认安装:
ansible --version

# 查看安装目录:
rpm -lq ansible

Ansible配置文件和命令

配置文件概述

/etc/ansible/ansible.cfg  # 主配置文件,配置ansible工作特性(一般无需修改)
/etc/ansible/hosts        # 主机清单(将被管理的主机放到此文件)
/etc/ansible/roles/       # 存放角色的目录

## Ansible 主机清单文件inventory /etc/ansible/hosts
# 1> ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
# 2> 默认的inventory file为/etc/ansible/hosts
# 3> inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成

## 文件格式:
# inventory文件遵循INI文件风格,中括号中的字符为组名。
# 可以将同一个主机同时归并到多个不同的组中;
# 此外,当目标主机使用了非默认的SSH端口(默认22),还可以在主机名称之后使用冒号加端口号来标明

## Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认)
[defaults]
#inventory     = /etc/ansible/hosts      # 主机列表配置文件
#library       = /usr/share/my_modules/  # 库文件存放目录
#remote_tmp    = $HOME/.ansible/tmp      # 临时py命令文件存放在远程主机目录
#local_tmp     = $HOME/.ansible/tmp      # 本机的临时命令执行目录
#forks         = 5                       # 默认并发数,同时可以执行5次
#sudo_user     = root                    # 默认sudo 用户
#ask_sudo_pass = True                    # 每次执行ansible命令是否询问ssh密码
#ask_pass      = True                    # 每次执行ansible命令是否询问ssh口令
#remote_port   = 22                      # 远程主机的端口号(默认22)

# 建议优化项:
#host_key_checking = False               # 检查对应服务器的host_key,建议取消注释,不取消的话必须连过ssh 已经增加到known_hosts文件里 才能连接成功
#log_path=/var/log/ansible.log           # 日志文件,建议取消注释,方便查看执行历史日志
#module_name   = command                 # 默认模块

Ansible系列命令

## 都是软连接
/usr/bin/ansible          # 主程序,临时命令执行工具
/usr/bin/ansible-doc      # 查看模块文档,如ansible-doc -s command,-s简要显示,-l列出所有模块,其他参数查看-h
/usr/bin/ansible-playbook # 定制自动化任务,编排剧本工具
/usr/bin/ansible-galaxy   # 下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-pull     # 远程执行命令的工具
/usr/bin/ansible-vault    # 文件加密工具
/usr/bin/ansible-console  # 基于Console界面与用户交互的执行工具


## 剧本 按照标准的yml语言写的脚本
ansible-playbook
ansible-playbook hello.yml	# 执行playbook

## 连接https://galaxy.ansible.com,下载指定galaxy(roles),开源的
ansible-galaxy list	# 列出所有已安装的galaxy
ansible-galaxy install geerlingguy.redis	# 安装galaxy
ansible-galaxy remove geerlingguy.redis	# 删除galaxy

## 推送命令至远程,效率无限提升,对运维要求较高
ansible-pull

## 管理加密解密yml文件(了解)
ansible-vault [create|decrypt|edit|encrypt|rekey|view]
    ansible-vault encrypt hello.yml # 加密
    ansible-vault decrypt hello.yml # 解密
    ansible-vault view hello.yml    # 查看
    ansible-vault edit hello.yml    # 编辑加密文件
    ansible-vault rekey hello.yml   # 修改口令
    ansible-vault create new.yml    # 创建新文件

## 2.0+新增,可交互执行命令,支持tab  (了解)
ansible-console
root@test (2)[f:10] $	# 执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$
# 设置并发数:         forks n   例如: forks 10
# 切换组:             cd 主机组 例如: cd web
# 列出当前组主机列表: list
# 列出所有的内置命令: ?或help
# 示例:
root@all (2)[f:5]$ list
root@all (2)[f:5]$ cd appsrvs
root@appsrvs (2)[f:5]$ list
root@appsrvs (2)[f:5]$ yum name=httpd state=present
root@appsrvs (2)[f:5]$ service name=httpd state=started

Ansible命令使用

ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点

ansible <host-pattern | all> [-m module_name] [-a 'args']
    --version              # 显示版本
    -m module              # 指定模块,默认为command
    -a 'p=1'               # 指定参数
    -v                     # 显示详细过程 –vv -vvv更详细
    --list-hosts           # 列出当前主机模式的主机列表,可简写 --list,如ansible servers --list
    -C, --check            # 检查,并不执行
    -T, --timeout=TIMEOUT  # 执行命令的超时时间,默认10s
    -u, --user=REMOTE_USER # 指定要连接的远程用户,如-u test1
    -k, --ask-pass         # 指定输入远程用户的口令验证,默认Key验证
    -b, --become           # 代替旧版的sudo切换,指定使用哪个用户执行命令,默认为root
        --become-user=USERNAME	# 指定作为哪个用户执行 比如 --become-user test1
    -K, --ask-become-pass  # 指定输入远程用户sudo时的验证,become指定的是命令再执行是先sudo
## 举例
ansible all -m shell -a 'ls /' --become-user root -K -u zhang -k # 此时需要输入要连接的zhang账户的密码,以及zhang用户substitute user为root的密码(远程主机)
ansible all --list  # 列出所有主机

## ping模块: 检测主机是否可以正常ssh,如果对方主机网络正常,返回pong
ansible-doc -s ping   # 查看ping模块的语法
ansible all -m ping -k	# 输入对方主机密码验证,默认会校验known_hosts,也即是需要连过,可以修改配置文件默认配置,改成不需要校验
ansible all -m ping		# 将公钥ssh-copy-id到被管理的主机上,即可使用基于key的验证
# 以zhang用户sudo至root用户,并输入ssh zhang的密码和sudo至root的密码测试
ansible all -m ping -u zhang -k -b --become-user=root -k -K
ansible all -m command -u zhang -a 'pwd' -b --become-user=root -k -K

Ansible命令参数中的Host-pattern

# all,表示所有Inventory中的所有主机,
ansible all –m ping

# 通配符:*
    ansible "*" -m ping  (*表示所有主机)
    ansible 192.168.1.* -m ping
    ansible "*srvs" -m ping

# 或关系 ":"
    ansible "websrvs:appsrvs" -m ping
    ansible "192.168.1.10:192.168.1.20" -m ping

# 逻辑与 ":&"
    ansible "websrvs:&dbsrvs" –m ping	# 在websrvs组并且在dbsrvs组中的主机

# 逻辑非 ":!"
    ansible 'websrvs:!dbsrvs' –m ping	# 在websrvs组,但不在dbsrvs组中的主机,注意:此处为单引号,建议都用单引号''

# 综合逻辑
    ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping

# 正则表达式
    ansible "websrvs:&dbsrvs" –m ping
    ansible "~(web|db).*\.magedu\.com" –m ping

Ansible命令执行过程

可以通过在ansible命令中加-vvvv查看

1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg
2. 加载自己对应的模块文件,如command
3. 通过ansible将模块或命令生成对应的临时py文件,
   并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
4. 给文件+x执行
5. 执行并返回结果
6. 删除临时py文件,sleep 0退出

执行状态:
    绿色:执行成功并且不需要做改变的操作
    黄色:执行成功并且对目标主机做变更
    红色:执行失败

Ansible常用模块

## command:在远程主机执行命令,默认模块,可忽略-m选项
    > ansible srvs -m command -a 'service vsftpd start'
    > ansible srvs -m command -a 'echo adong |passwd --stdin 123456'
# 注意,此命令不支持 $VARNAME < > | ; & 等,可以用shell模块实现

## shell:和command相似,用shell执行命令
    > ansible all -m shell  -a 'getenforce'  查看SELINUX状态
    > ansible all -m shell  -a "sed -i 's/SELINUX=.*/SELINUX=disabled' /etc/selinux/config"
    > ansible srv -m shell -a 'echo magedu |passwd –stdin wang'
# 注意,调用bash执行命令 类似 cat /tmp/stanley.md | awk -F'|' '{print $1,$2}' &> /tmp/example.txt 这些复杂命令,即使使用shell也可能会失败,解决办法:写到脚本时,copy到远程执行,再把需要的结果拉回执行命令的机器

# script:在远程主机上运行当前服务器上的脚本,自动将脚本拷贝过去并执行
    > ansible websrvs -m script -a /data/test.sh

# copy:从主控端复制文件到远程主机,只能复制文件
    > ansible websrvs -m copy -a "src=/root/test1.sh dest=/tmp/test2.showner=wang mode=600 backup=yes" # 如果目标存在,默认覆盖,此处指定先备份
    > ansible websrvs -m copy -a "content='test content\nxxx' dest=/tmp/test.txt" # 指定内容,直接生成目标文件

# fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录,可以先打包,再提取文件
    > ansible websrvs -m fetch -a 'src=/root/test.sh dest=/data/scripts' # 会生成每个被管理主机不同编号的目录,不会发生文件名冲突
    > ansible all -m shell -a 'tar jxvf test.tar.gz /root/test.sh'
    > ansible all -m fetch -a 'src=/root/test.tar.gz dest=/data/'

# file:创建文件、连接,删除文件,设置属性
    > ansible websrvs -m file -a 'path=/app/test.txt state=touch'       # 创建文件
    > ansible websrvs -m file -a "path=/data/testdir state=directory"   # 创建目录
    > ansible websrvs -m file -a "path=/root/test.sh owner=wang mode=755"  # 设置权限755
    > ansible websrvs -m file -a 'src=/data/testfile dest=/data/testfile-link state=link' # 创建软链接

# unarchive:解压,将ansible主机压缩包分别解压到远程主机(copy=yes),或解压远程主机上的压缩包(copy=no)
ansible websrvs -m unarchive -a 'src=foo.tgz dest=/var/lib/foo' # 默认copy为yes,将本机目录文件解压到目标主机对应目录下
ansible websrvs -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777' # 解压被管理主机的foo.zip到data目录下, 并设置权限777
ansible websrvs -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'

# archive:打包压缩,将远程主机目录打包,并收集到ansible主机
    > ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=wang mode=0777'

# hostname:管理主机名
    ansible appsrvs -m hostname -a "name=app.adong.com"  更改一组的主机名
    ansible 192.168.38.103 -m hostname -a "name=app2.adong.com" 更改单个主机名

# cron:计划任务,支持时间:minute,hour,day,month,weekday,/usr/bin/wall warning 广播信息
    > ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime" # 创建任务
    > ansible websrvs -m cron -a 'state=absent name=Synctime' # 删除任务
    > ansible websrvs -m cron -a 'minute=*/10 job="/usr/sbin/ntpdate 172.30.0.100" name=synctime disabled=yes' # 注释任务,不在生效

# yum:管理包,可以同时安装多个程序包
    ansible websrvs -m yum -a 'list=httpd' # 查看程序列表
    ansible websrvs -m yum -a 'name=httpd state=present' # 安装
    ansible websrvs -m yum -a 'name=httpd state=absent' # 删除

# service:管理服务
    ansible srv -m service -a 'name=httpd state=stopped' # 停止服务
    ansible srv -m service -a 'name=httpd state=started enabled=yes' # 启动服务,并设为开机自启
    ansible srv -m service -a 'name=httpd state=reloaded' # 重新加载
    ansible srv -m service -a 'name=httpd state=restarted' # 重启服务

# user:管理用户
    ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
    ansible websrvs -m user -a 'name=sysuser1 system=yes home=/app/sysuser1'
    ansible websrvs -m user -a 'name=app uid=88 system=yes home=/app groups=root shell=/sbin/nologin password="$1$zfVojmPy$ZILcvxnXljvTI2PhP2Iqv1"' # 创建用户
    ansible websrvs -m user -a 'name=app state=absent' # 不会删除家目录
    ansible websrvs -m user -a 'name=user1 state=absent remove=yes'  # 清空用户所有数据,用户及家目录等数据

# group:管理组
    ansible srv -m group -a "name=testgroup system=yes" # 创建组
    ansible srv -m group -a "name=testgroup state=absent" # 删除组

Playbook

playbook是由一个或多个"play"组成的列表,play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按事先编排的机制执行预定义的动作。Playbook采用YAML语言编写

playbook图解:

用户通过ansible命令直接调用yml语言写好的playbook,playbook由多条play组成,每条play都有一个任务(task)相对应的操作,然后调用模块modules,应用在主机清单上,通过ssh远程连接,从而控制远程主机或者网络设备

YAML介绍:

YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者

"YAML Aint Markup Language",即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)

特性
    YAML的可读性好
    YAML和脚本语言的交互性好
    YAML使用实现语言的数据类型
    YAML有一个一致的信息模型
    YAML易于实现
    YAML可以基于流来处理
    YAML表达能力强,扩展性好

更多的内容及规范参见:http://www.yaml.org

YAML语法简介:

> 在单一档案中,可用连续三个连字号(——)区分多个档案。
  另外,还有选择性的连续三个点号( ... )用来表示档案结尾
> 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
> 使用#号注释代码
> 缩进必须是统一的,不能空格和tab混用
> 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的
> YAML文件内容是区别大小写的,k/v的值均需大小写敏感
> 多个k/v可同行写也可换行写,同行使用:分隔
> v可是个字符串,也可是另一个列表[]
> 一个完整的代码块功能需最少元素需包括 name 和 task
> 一个name只能包括一个task
> YAML文件扩展名通常为yml或yaml

yaml示例:

# List:列表,其所有元素均使用“-”打头,列表代表同一类型的元素
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango

# Dictionary:字典,通常由多个key与value构成 键值对
---
# An employee record
name: Example Developer
job: Developer
skill: Elite

# 也可以将key:value放置于{}中进行表示,用,分隔多个key:value
---
# An employee record
{name: Example Developer, job: Developer, skill: Elite}  有空格

# YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构通过空格来展示,序列里的项用"-"来代表,Map里的键值对用":"分隔

name: John Smith
age: 41
gender: Male
spouse:
  name: Jane Smith
  age: 37
  gender: Female
children:
  - name: Jimmy Smith
    age: 17
    gender: Male
  - name: Jenny Smith
    age 13
    gender: Female

Playbook核心元素

Hosts          执行的远程主机列表(应用在哪些主机上)

Tasks          任务集

Variables      内置变量或自定义变量在playbook中调用

Templates模板  可替换模板文件中的变量并实现一些简单逻辑的文件

Handlers和notify结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行

tags标签       指定某条任务执行,用于选择运行playbook中的部分代码。
                ansible具有幂等性,因此会自动跳过没有变化的部分,
                即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。
                此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
                ansible-playbook -t tagsname useradd.yml

playbook核心元素说明:

## hosts:与ansible命令中的host-pattern使用相同,只是放在了playbook里面
# playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
# 示例:
- hosts: websrvs:dbsrvs

## remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
# 示例:
- hosts: websrvs
  remote_user: root   # (可省略,默认为root)  以root身份连接
  tasks:    # 指定任务
    - name: test connection
      ping:
      remote_user: magedu
      sudo: yes           # 默认sudo为root
      sudo_user: wang     # sudo为wang

## task列表和action
# 任务列表task:由多个动作,多个任务组合起来的,每个任务都调用的模块,一个模块一个模块执行
#   1> play的主体部分是task list,task list中的各任务按次序逐个在hosts中指定的所有主机上执行,
#      即在所有主机上完成第一个任务后,再开始第二个任务
#   2> task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。
#      模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
#   3> 每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。
#      如果未提供name,则action的结果将用于输出

## tasks:任务列表,两种格式:
#    (1) action: module arguments
#    (2) module: arguments 建议使用  模块: 参数
#    注意:shell和command模块后面跟命令,而非key=value

## notify和handlers:某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers
# handlers并不是马上执行的,而是执行完所有的task之后再去顺序执行handlers里面定义的被notify的handler,如果需要立即执行,需要在任务之后添加meta模块:
- meta: flush_handlers # 立即之前该任务之前被notify的handler
# 如果需要通知多个handler,可以将多个handler设置为相同的组(使用listen),然后notify这个组即可

## tags:任务可以通过"tags"打标签,可在ansible-playbook命令上使用-t进行调用指定task
# 示例:
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  # 忽略错误

运行playbook

ansible-playbook <filename.yml> ... [options]
# 常见选项
    -t tag1,tag2     # 按照tags执行
    --check -C       # 只检测可能会发生的改变,但不真正执行操作,(只检查语法,如果执行过程中出现问题,-C无法检测出来),(执行playbook生成的文件不存在,后面的程序如果依赖这些文件,也会导致检测失败)
    --list-hosts     # 列出运行任务的主机
    --list-tags      # 列出tag  (列出标签)
    --list-tasks     # 列出task (列出任务)
    --limit # 主机列表 只针对主机列表中的主机执行
    -v -vv -vvv      # 显示过程

# 示例
    ansible-playbook hello.yml --check 只检测
    ansible-playbook hello.yml --list-hosts  显示运行任务的主机
    ansible-playbook hello.yml --limit websrvs  限制主机

Playbook示例:安装httpd

  • SHELL脚本方式
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
service httpd start
chkconfig httpd on
  • Playbook方式
---
- hosts: all
  remote_user: root

  tasks:
    - name: "安装Apache"
      yum: name=httpd       # yum模块:安装httpd
    - name: "复制配置文件"
      copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/  # copy模块: 拷贝文件
    - name: "复制配置文件"
      copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
    - name: "启动Apache,并设置开机启动"
      service: name=httpd state=started enabled=yes   # service模块: 启动服务

Playbook示例:创建用户

---
- hosts: all
  remote_user: root

  tasks:
    - name: create mysql user
      user: name=mysql system=yes uid=36
    - name: create a group
      group: name=httpd system=yes

Playbook示例:安装httpd服务

- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
    - name: start service
      service: name=httpd state=started enabled=yes

Playbook示例:安装nginx服务

- hosts: all
  remote_user: root

  tasks:
    - name: add group nginx
      user: name=nginx state=present
    - name: add user nginx
      user: name=nginx state=present group=nginx
    - name: Install Nginx
      yum: name=nginx state=present
    - name: Start Nginx
      service: name=nginx state=started enabled=yes

handlers和notify结合使用触发条件

# Handlers 实际上就是一个触发器,是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作

#Notify 此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。

# 在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

Playbook示例:handlers使用

- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd # 可以定义为列表,触发执行多个task
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

Playbook示例:handlers使用

- hosts: webnodes
  vars:
    http_port: 80
    max_clients: 256
  remote_user: root

  tasks:
    - name: ensure apache is at the latest version
      yum: name=httpd state=latest
    - name: ensure apache is running
      service: name=httpd state=started
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd

  handlers:
      - name: restart httpd
        service: name=httpd state=restarted

Playbook示例:handlers使用

- hosts: websrvs
  remote_user: root

  tasks:
    - name: add group nginx
      tags: user
      user: name=nginx state=present
    - name: add user nginx
      user: name=nginx state=present group=nginx
    - name: Install Nginx
      yum: name=nginx state=present
    - name: config
      copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
      notify:
        - Restart Nginx
        - Check Nginx Process

  handlers:
    - name: Restart Nginx
      service: name=nginx state=restarted enabled=yes
    - name: Check Nginx process
      shell: killall -0 nginx > /tmp/nginx.log

Playbook中tags的使用

添加标签,可以指定某一个任务添加一个标签,添加标签以后,想执行某个动作可以做出挑选来执行,多个动作可以使用同一个标签

Playbook示例:tags使用

- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
      tags: install # 应该也可以定义列表 有多个标签
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      tags: conf
    - name: start httpd service
      tags: service
      service: name=httpd state=started enabled=yes

# ansible-playbook –t install,conf httpd.yml   # 指定执行install,conf 两个标签

Playbook示例:tags使用

- hosts: testsrv
  remote_user: root
  tags: inshttpd   # 也可以针对整个playbook添加tag
  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      tags: rshttpd
      notify: restart httpd
  handlers:
    - name: restart httpd
      service: name=httpd status=restarted

# ansible-playbook –t rshttpd httpd2.yml

Playbook中变量的使用

# 变量命名:仅能由字母、数字和下划线组成,且只能以字母开头
# 变量来源:
    1> ansible setup facts 远程主机的所有变量都可直接调用 (系统自带变量)
       setup模块可以实现系统中很多系统信息的显示,可以返回每个主机的系统信息包括:版本、主机名、cpu、内存,也可以注册变量到facts
       ansible all -m setup -a 'filter="ansible_nodename"'     查询主机名
       ansible all -m setup -a 'filter="ansible_memtotal_mb"'  查询主机内存大小
       ansible all -m setup -a 'filter="ansible_distribution_major_version"'  查询系统版本
       ansible all -m setup -a 'filter="ansible_processor_vcpus"' 查询主机cpu个数

    2> 在/etc/ansible/hosts(主机清单)中定义变量
        普通变量:主机组中主机单独定义,优先级高于公共变量(单个主机 )
        公共(组)变量:针对主机组中所有主机定义统一变量(一组主机的同一类别)
       vim /etc/ansible/hosts
       [appsrvs]
       192.168.38.17 http_port=817 name=www # 针对主机设置变量
       192.168.38.27 http_port=827 name=web
       [appsrvs:vars] # 针对一组设置变量
       name="xxx"

    3> 通过命令行指定变量,优先级最高
       ansible-playbook –e 'varname=value'

    4> 在playbook中定义
       vars:
        - var1: value1
        - var2: value2

    5> 在独立的变量YAML文件中定义

    6> 在role中定义

# 变量调用方式:
    1> 通过{{ variable_name }} 调用变量,有时用"{{ variable_name }}"才生效

    2> ansible-playbook –e 选项指定
       ansible-playbook test.yml -e "hosts=www user=magedu"

## 使用示例
ansible appsrvs -m hostname -a 'name={{name}}'  # 更改主机名为各自被定义的变量
ansible appsrvs -m hostname -a 'name={{name}}{{mark}}{{http_port}}'

使用示例:yaml中定义变量,将变量写进单独的配置文件中,然后引用配置文件

# vim vars.yml
pack: vsftpd
service: vsftpd

# 引用变量文件
vars_files:
  - vars.yml

使用示例:使用setup模块的内部变量,包括自己注册变量

## Facts:是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主机所支持的所有facts,可使用如下命令进行查看:
ansible websrvs -m setup
# 示例:
- hosts: websrvs
  remote_user: root
  tasks:
    - name: create log file
      file: name=/var/log/ {{ ansible_fqdn }} state=touch

## register注册变量:把任务的输出定义为变量,然后用于其他任务
# 示例:
tasks:
- shell: /usr/bin/foo
  register: foo_result
  ignore_errors: True

使用示例:命令行定义变量

- hosts: websrvs
  remote_user: root
vars:
  - username: user1
  - groupname: group1
tasks:
  - name: create group
    group: name={{ groupname }} state=present
  - name: create user
    user: name={{ username }} state=present

# ansible-playbook -e "username=user2 groupname=group2” var2.yml

使用示例:使用主机清单中的变量,普通变量和组变量
可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用

## 普通变量
    [websrvs]
    192.168.99.101 http_port=8080 hname=www1
    192.168.99.102 http_port=80 hname=www2

## 公共(组)变量,组变量是指赋予给指定组内所有主机上的在playbook中可用的变量
    [websvrs:vars]
    http_port=808
    mark="_"
    [websrvs]
    192.168.99.101 http_port=8080 hname=www1
    192.168.99.102 http_port=80 hname=www2
    ansible websvrs –m hostname –a ‘name={{ hname }}{{ mark }}{{ http_port }}’

## 命令行使用变量:
    ansible websvrs –e http_port=8000 –m hostname –a'name={{ hname }}{{ mark }}{{ http_port }}'

使用示例:使用变量文件

# cat vars.yml
var1: httpd
var2: nginx

# cat var.yml
- hosts: web
  remote_user: root
  vars_files:
    - vars.yml # 这里写变量文件的路径,如果是相对路径是性对于playbook的yml文件的路径
  tasks:
    - name: create httpd log
      file: name=/app/{{ var1 }}.log state=touch
    - name: create nginx log
      file: name=/app/{{ var2 }}.log state=touch

# hostname app_81.magedu.com  hostname # hostname模块不支持"_",认为"_"是非法字符
# hostnamectl set-hostname app_80.magedu.com # 可以更改主机名

inventory组嵌套中的变量:
inventory中,组还可以包含其它的组,并且也可以向组中的主机指定变量。这些变量只能在ansible-playbook中使用,而ansible命令不支持

[apache]
httpd1.magedu.com
httpd2.magedu.com

[nginx]
ngx1.magedu.com
ngx2.magedu.com

[websrvs:children]
apache
nginx

[webservers:vars]
ntp_server=ntp.magedu.com

invertory参数

用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量

ansible_ssh_host # The name of the host to connect to, if different from the alias you wishto give to it.
ansible_ssh_port # The ssh port number, if not 22
ansible_ssh_user # The default ssh user name to use.
ansible_ssh_pass # The ssh password to use (this is insecure, we strongly recommendusing --ask-pass or SSH keys)
ansbile_sudo_pass # The sudo password to use (this is insecure, we strongly recommendusing --ask-sudo-pass)

ansible_connection # Connection type of the host. Candidates are local, ssh or paramiko. The default is paramiko before Ansible 1.2, and 'smart' afterwards which detects whether usage of 'ssh' would be feasible based on whether ControlPersist is supported.

ansible_ssh_private_key_file # Private key file used by ssh. Useful if using multiple keys and you don't want to use SSH agent.

ansible_shell_type # The shell type of the target system. By default commands are formatted using 'sh'-style syntax by default. Setting this to 'csh' or 'fish' will cause commands executed on target systems to follow those shell's syntax instead.

ansible_python_interpreter # The target host python path. This is useful for systems with more than one Python or not located at "/usr/bin/python" such as \*BSD, or where /usr/bin/python is not a 2.X series Python. We do not use the "/usr/bin/env" mechanism as that requires the remote user's path to be set right and also assumes the "python" executable is named python,where the executable might be named something like "python26".

ansible\_\*\_interpreter # Works for anything such as ruby or perl and works just like ansible_python_interpreter. This replaces shebang of modules which will run on that host.

# 定义示例: cat /etc/ansible/hosts
[websrvs]
192.168.0.1 ansible_ssh_user=root ansible_ssh_pass=magedu
192.168.0.2 ansible_ssh_user=root ansible_ssh_pass=magedu

在Playbook中使用模板template

template是一个模块,且只能用于playbook,不能用于ansible命令行(ad-hoc点对点)

# 文本文件,嵌套有脚本(使用模板编程语言编写),借助模板生成真正的文件
# Jinja2语言,使用字面量,有下面形式
    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1, item2, ...]
    元组:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布尔型:true/false
算术运算:+, -, *, /, //, %, **
比较操作:==, !=, >, >=, <, <=
逻辑运算:and,or,not
流表达式:For,If,When

## 字面量
    1> 表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 Python对象。如“Hello World”
    双引号或单引号中间的一切都是字符串。
    2> 无论何时你需要在模板中使用一个字符串(比如函数调用、过滤器或只是包含或继承一个模板的参数),如4242.23
    3> 数值可以为整数和浮点数。如果有小数点,则为浮点数,否则为整数。在Python 里, 42 和 42.0 是不一样的

## 算术运算,Jinja 允许你用计算值。这在模板中很少用到,但为了完整性允许其存在,支持下面的运算符
+	# 把两个对象加到一起。通常对象是素质,但是如果两者是字符串或列表,你可以用这种方式来衔接它们。无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。 {{ 1 + 1 }} 等于 2
-	# 用第一个数减去第二个数。 {{ 3 - 2 }} 等于 1
/	# 对两个数做除法。返回值会是一个浮点数。 {{ 1 / 2 }} 等于 {{ 0.5 }}
//	# 对两个数做除法,返回整数商。 {{ 20 // 7 }} 等于 2
%	# 计算整数除法的余数。 {{ 11 % 7 }} 等于 4
*	# 用右边的数乘左边的操作数。 {{ 2 * 2 }} 会返回4,也可以用于重复一个字符串多次。{{ '=' * 80 }} 会打印 80 个等号的横条
**	# 取左操作数的右操作数次幂。 {{ 2**3 }} 会返回8

## 比较操作符
== # 比较两个对象是否相等
!= # 比较两个对象是否不等
>  # 如果左边大于右边,返回 true
>= # 如果左边大于等于右边,返回 true
<  # 如果左边小于右边,返回 true
<= # 如果左边小于等于右边,返回 true

## 逻辑运算符
# 对于if语句,在for过滤或if表达式中,它可以用于联合多个表达式
and	# 如果左操作数和右操作数同为真,返回 true
or	# 如果左操作数和右操作数有一个为真,返回 true
not	# 对一个表达式取反(见下)
(expr)	# 表达式组

## 列表 ['list', 'of', 'objects']
# 一对中括号括起来的东西是一个列表。列表用于存储和迭代序列化的数据。例如 你可以容易地在for循环中用列表和元组创建一个链接的列表
    <ul>
    {% for href, caption in [('index.html', 'Index'), ('about.html', 'About'), ('downloads.html', 'Downloads')] %}
        <li><a href="{{ href }}">{{ caption }}</a></li>
    {% endfor %}
    </ul>
    ('tuple', 'of', 'values'):

## 元组与列表类似,只是你不能修改元组。如果元组中只有一个项,你需要以逗号结尾它。元组通常用于表示两个或更多元素的项。
{'dict': 'of', 'key': 'and', 'value': 'pairs'}:

## Python中的字典是一种关联键和值的结构。键必须是唯一的,并且键必须只有一个值。字典在模板中很少使用,罕用于诸如 xmlattr()过滤器之类

template的使用:根据模块文件动态生成对应的配置文件

   > template文件必须存放于与templates目录下,且命名为.j2结尾
   > yaml/yml文件需要与templates目录平级,目录结构如下:
    ./
     ├── your_playbook.yml
     └── templates
        └── your_conf_file.conf.j2

使用示例:使用template同步nginx配置文件

# 准备templates/nginx.conf.j2文件
# vim temnginx.yml
- hosts: websrvs
  remote_user: root
  tasks:
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

# ansible-playbook temnginx.yml # 生成的nginx.conf文件里面的变量都是被替换后的

## 模板中使用算术运算
# vim nginx.conf.j2
# worker_processes {{ ansible_processor_vcpus**2 }};
# worker_processes {{ ansible_processor_vcpus+2 }};

## 模板中使用jinja2的语法:if,for
{% for vhost in nginx_vhosts %} # 使用数组变量进行循环
listen {{ vhost.listen | default('80 default_server') }}; # 会重复生成的内容
{% if vhost.server_name is defined %} # 使用if判断变量是否定义
server_name {{ vhost.server_name }};
{% endif %}
{% endfor %}

Playbook中的when语句实现条件判断

## 如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when语句实现,在task中使用,支持jinja2的语法格式
tasks:
  - name: "shutdown RedHat flavored systems"
    command: /sbin/shutdown -h now
    when: ansible_os_family == "RedHat"  # 当系统属于红帽系列,执行command模块

## when语句中还可以使用Jinja2的大多"filter",例如要忽略此前某语句的错误并基于其结果(failed或者success)运行后面指定的语句,可使用类似如下形式:
tasks:
  - command: /bin/false
    register: result
    ignore_errors: True
  - command: /bin/something
    when: result|failed
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped

## 此外,when语句中还可以使用facts或playbook中定义的变量
tasks:
  - name: install conf file to centos7
    template: src=nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
    when: ansible_distribution_major_version == "7" # 使用facts变量判断
  - name: install conf file to centos6
    template: src=nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
    when: ansible_distribution_major_version == "6" # 使用facts变量判断

Playbook中的with_items语句实现迭代

# 当有需要重复性执行的任务时,可以使用迭代机制
#    > 对迭代项的引用,固定变量名为"item"
#    > 要在task中使用with_items给定要迭代的元素列表
#    > 列表格式:
#         字符串
#         字典
# 举例:
- name: add several users
  user: name={{ item }} state=present groups=wheel   # item是系统自定义变量
  with_items:       # 定义item的值和个数
    - testuser1
    - testuser2
# 举例:也可以定义为字典 迭代嵌套子变量
- name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' }
    - { name: 'testuser2', groups: 'root' }

# ansible的循环机制还有更多的高级功能,具体请参见官方文档
# http://docs.ansible.com/playbooks_loops.html

Roles

  • ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
  • 复杂场景:建议使用roles,代码复用度高,变更指定主机或主机组,如命名不规范维护和传承成本大,某些功能需多个Playbook,通过includes即可实现

Roles目录结构

# 每个角色,以特定的层级目录结构进行组织
my-playbook/
  role_call.yml  # 用于调用角色的简单剧本,需要制定role,默认查找目录:当前同级目录、同级目录中的roles目录、 ~/.ansible/roles,只要库在上述目录找到这个role都可以正确调用。也可以修改配置文件,增加扫描的目录roles_path=/etc/ansible/roles:/opt:/testdir
  roles/
    role_name/ # 角色名称,在roles目录下可以由多个角色
      tasks/
      files/
      vars/
      templates/
      handlers/
      default/ # roles使用的默认变量,不常用
      meta/    # 指定一些系统配置,不常用
# roles之间可以互相调用,在tasks/main.yml里面include时写别的角色的task文件的绝对目录即可
# group_vars/all存放所有主机都可以使用的变量,可以针对主机组如dbservers创建dbservers.yml变量文件,只针对该主机组,且优先级大于all.yml
# 变量文件优先级:-e > vars/main.yml > defaults/main.yml > hosts > group_vars/*。roles中的变量是全局可访问的,可以修改配置文件变为私有

## Roles各目录作用
/roles/project/ # 项目名称,有以下子目录
    files/ # 存放由copy或script模块等调用的文件
    templates/ # template模块查找所需要模板文件的目录
    tasks/ # 定义此角色的任务列表,至少应该包含一个名为main.yml的文件,其它的文件需要在此文件中通过include进行包含
    handlers/ # 定义handler,被notify调用,至少应该包含一个名为main.yml的文件,其它的文件需要在此文件中通过include进行包含
    vars/ # 定义此角色用到的变量,至少应该包含一个名为main.yml的文件,其它的文件需要在此文件中通过include进行包含
    meta/ # 定义当前角色的特殊设定及其依赖关系,1.3及其以后的版本才支持,至少应该包含一个名为main.yml的文件, 其它文件需在此文件中通过include进行包含(不常用)
    default/ # 为当前角色设定默认变量时使用此目录,应包含main.yml文件(不常用)

roles/example_role/files/            #  所有文件,都将可存放在这里
roles/example_role/templates/        #  所有模板都存放在这里
roles/example_role/tasks/main.yml   # 主函数,包括在其中的所有任务将被执行
roles/example_role/handlers/main.yml # 所有包括其中的 handlers 将被执行
roles/example_role/vars/main.yml    # 所有包括在其中的变量将在roles中生效
roles/example_role/meta/main.yml    # roles所有依赖将被正常登入

创建Role

创建role的步骤
(1) 创建以roles命名的目录
(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等
(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;
    用不到的目录可以创建为空目录,也可以不创建
(4) 在playbook文件中,调用各角色

使用示例:创建httpd角色

## 创建roles目录结构(一般roles里面可以只写一个role,roles目录和同目录下的yml放在一个目录下)
tree roles/
    roles/
    ├── httpd
    │   ├── files
    │   ├── handlers
    │   └── tasks
    ├── mysql
    │   └── tasks
    └── redis
        └── tasks

## 创建task文件
   cd roles/httpd/tasks/
   touch install.yml config.yml service.yml
# vim install.yml
   - name: install httpd package
     yum: name=httpd
# vim config.yml
   - name: config file
     copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
# vim service.yml
   - name: start service
     service: name=httpd state=started enabled=yes

## 创建main.yml主控文件,调用以上单独的yml文件, main.yml定义了task执行的顺序
   - include: install.yml
   - include: config.yml
   - include: service.yml
     tags:
       - hi2 # 增加tags

- include_tasks: # 使用include_tasks,相比于include,include更透明
    file: test.yml
    apply:
      tags: hi1
  tags: always # 写成always 或者与里面的tags写的相同 这里的tags只是会执行include_tasks 并不执行里面的task 增加了file和apply才可以

## 用到的模板文件放在templates下,用到的文件放到files下

## 根据需要使用handlers目录,创建main.yml 写task或者include

## 创建文件调用httpd角色,vim role_httpd.yml
    ---
    # httpd role
    - name: role to do description. # 可选
      hosts: appsrvs
      remote_user: root # 可选
      roles:       # 调用角色
        - role: httpd # 这里也可以指定tags,when,dir,可以使用{}直接指定字典
## 执行playbook:ansible-playbook role_httpd.yml,也可以根据tags执行 -t your_tags

Role的其他参数及使用

- hosts:
  remote_user:
  roles:
    - mysql
    - { role: nginx, username: nginx } # 向roles传递参数
    - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' } # 基于条件使用role
    - { role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080 } # dir指定role的绝对路径
    - { role: httpd, tags: [ 'httpd', 'web' ] } # 给role定义tag

posted on 2022-06-05 20:28  Bingmous  阅读(380)  评论(0编辑  收藏  举报