24-运维自动化之ANSIBLE

本章内容

◆ 运维自动化发展历程及技术应用
◆ Ansible命令使用
◆ Ansible常用模块详解
◆ YAML语法简介
◆ Ansible playbook基础
◆ Playbook变量、 tags、 handlers使用
◆ Playbook模板templates
◆ Playbook条件判断 when
◆ Playbook字典 with_items
◆ Ansible Roles

企业实际应用场景分析

Dev开发环境
    使用者:程序员
    功能:程序员开发软件,测试BUG的环境
    管理者:程序员
测试环境
    使用者:QA测试工程师
    功能:测试经过Dev环境测试通过的软件的功能
    管理者:运维
    说明:测试环境往往有多套,测试环境满足测试功能即可,不宜过多
    1、测试人员希望测试环境有多套,公司的产品多产品线并发,即多个版本,意味着多个版本同步测试
    2、通常测试环境有多少套和产品线数量保持一样  
    
发布环境:代码发布机,有些公司为堡垒机(安全屏障)
    使用者:运维
    功能:发布代码至生产环境
    管理者:运维(有经验)
    发布机:往往需要有2台(主备)
生产环境
    使用者:运维,少数情况开放权限给核心开发人员,极少数公司将权限完全开放给开发人员并其维护
    功能:对用户提供公司产品的服务
    管理者:只能是运维
    生产环境服务器数量:一般比较多,且应用非常重要。往往需要自动工具协助部署配置应用
    
灰度环境(生产环境的一部分)
    使用者:运维
    功能:在全量发布代码前将代码的功能面向少量精准用户发布的环境,可基于主机或用户执行灰度发布
    案例:共100台生产服务器,先发布其中的10台服务器,这10台服务器就是灰度服务器
    管理者:运维
    灰度环境:往往该版本功能变更较大,为保险起见特意先让一部分用户优化体验该功能,待这部分用户使用没有重大问题的时候,再全量发布至所有服务器    

程序发布

● 程序发布要求:
    不能导致系统故障或造成系统完全不可用
    不能影响用户体验
● 预发布验证:
    新版本的代码先发布到服务器(跟线上环境配置完全相同,只是未接入到调度器)
● 灰度发布:
    基于主机,用户,业务
● 发布路径:
    /webapp/tuangou
    /webapp/tuangou-1.1
    /webapp/tuangou-1.2
● 发布过程:在调度器上下线一批主机(标记为maintanance状态) --> 关闭服务 --> 部署新版本的应用程序 --> 启动服务 --> 在调度器上启用这一批服务器
● 自动化灰度发布:脚本、发布平台

自动化运维应用场景

● 文件传输
● 应用部署
● 配置管理
● 任务流编排  

常用自动化运维工具

● Ansible:python,Agentless,中小型应用环境
● Saltstack:python,一般需部署agent,执行效率更高
● Puppet:ruby, 功能强大,配置复杂,重型,适合大型环境
● Fabric:python,agentless
● Chef:ruby,国内应用少
● Cfengine
● func  

Ansible发展史

Ansible
    创始人,Michael DeHaan( Cobbler 与 Func 的作者)
    2012-03-09,发布0.0.1版,红帽收购
    2015-10-17,Red Hat宣布收购
同类自动化工具GitHub关注程度(2016-07-10)
自动化运维工具 Watch(关注) Star(点赞) Fork(复制) Contributors(贡献者)
Ansible 1387 17716 5356 1428
Saltstack 530 6678 3002 1520
Puppet 463 4044 1678 425
Chef 383 4333 1806 464
Fabric 379 7334 1235 116

特性

● 模块化:调用特定的模块,完成特定任务
● 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
● 支持自定义模块
● 基于Python语言实现
● 部署简单,基于python和SSH(默认已安装),agentless
● 安全,基于OpenSSH
● 支持playbook编排任务
● 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
● 无需代理不依赖PKI(无需ssl)
● 可使用任何编程语言写模块
● YAML格式,编排任务,支持丰富的数据结构
● 较强大的多层解决方案 

ansible架构

image.png

Ansible工作原理

image.png

Ansible主要组成部分

● ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件
● INVENTORY:Ansible管理主机的清单/etc/anaible/hosts
● MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
● PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
● API:供第三方程序调用的应用程序编程接口
● ANSIBLE:组合INVENTORY、 API、 MODULES、 PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具

● Ansible命令执行来源:
    USER,普通用户,即SYSTEM ADMINISTRATOR
    CMDB(配置管理数据库) API 调用
    PUBLIC/PRIVATE CLOUD API调用
    USER-> Ansible Playbook -> Ansibile
● 利用ansible实现管理的方式:
    Ad-Hoc 即ansible命令,主要用于临时命令使用场景
    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不能做为主控端  

安装

rpm包安装: EPEL源
    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 zlib-devel rpm-bulid openssl-devel
    pip install --upgrade pip
    pip install ansible --upgrade
确认安装:
    ansible --version   

相关文件

配置文件
    /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
    /etc/ansible/hosts 主机清单
    /etc/ansible/roles/ 存放角色的目录
程序
    /usr/bin/ansible 主程序,临时命令执行工具
    /usr/bin/ansible-doc 查看配置文档,模块功能查看工具
    /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
    /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
    /usr/bin/ansible-pull 远程执行命令的工具
    /usr/bin/ansible-vault 文件加密工具
    /usr/bin/ansible-console 基于Console界面与用户交互的执行工具

主机清单inventory

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

● /etc/ansible/hosts文件格式
● inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明
    ntp.magedu.com
    [webservers]
    www1.magedu.com:2222
    www2.magedu.com
    [dbservers]
    db1.magedu.com
    db2.magedu.com
    db3.magedu.com
    
● 如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机
● 示例:
    [websrvs]
    www[1:100].example.com
    [dbsrvs]
    db-[a:f].example.com    

ansible 配置文件

● 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 # 默认并发数
    #sudo_user = root # 默认sudo 用户
    #ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
    #ask_pass = True
    #remote_port = 22
    #host_key_checking = False # 检查对应服务器的host_key,建议取消注释
    #log_path=/var/log/ansible.log #日志文件
    #module_name = command #默认模块

ansible系列命令

● Ansible系列命令
    ansible ansible-doc ansible-playbook ansible-vault ansible-console
    ansible-galaxy ansible-pull
● ansible-doc: 显示模块帮助
    ansible-doc [options] [module...]
    -a 显示所有模块的文档
    -l, --list 列出可用模块
    -s, --snippet显示指定模块的playbook片段
    示例:
    ansible-doc -l 列出所有模块
    ansible-doc ping 查看指定模块帮助用法
    ansible-doc -s ping 查看指定模块帮助用法 

● ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点
● ansible  [-m module_name] [-a args]
    --version 显示版本
    -m module 指定模块,默认为command
    -v 详细过程 –vv -vvv更详细
    --list-hosts 显示主机列表,可简写 --list
    -k, --ask-pass 提示输入ssh连接密码,默认Key验证
    -C, --check 检查,并不执行
    -T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
    -u, --user=REMOTE_USER 执行远程执行的用户
    -b, --become 代替旧版的sudo 切换
    --become-user=USERNAME 指定sudo的runas用户,默认为root
    -K, --ask-become-pass 提示输入sudo时的口令
    
● 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使用

vim /etc/ansible/hosts
    [websrvs]
    192.168.37.6
    192.168.37.17
    
    [appsrvs]
    192.168.37.[1:2]7
:wq
ansilbe all --list-hosts            #显示可管理机器
vim /etc/ansible/ansible.cfg
    [defaults]
    host_key_checking = False
:wq
ansilbe 192.168.37.6 -m ping -k     # -k 基于密码验证去ping
ansilbe all -m ping -k
  • 基于key验证
ssh-keygen
ssh-copy-id 192.168.37.6
ssh-copy-id 192.168.37.17
ssh-copy-id 192.168.37.27

ansilbe all -m ping

ansible命令执行过程

● ansible命令执行过程
    1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg
    2. 加载自己对应的模块文件,如command
    3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
    4. 给文件+x执行
    5. 执行并返回结果
    6. 删除临时py文件,退出
● 执行状态:
    绿色:执行成功并且不需要做改变的操作
    黄色:执行成功并且对目标主机做变更
    红色:执行失败  

ansible使用示例

示例
    以wang用户执行ping存活检测
        ansible all -m ping -u wang -k
    以wang sudo至root执行ping存活检测
        ansible all -m ping -u wang -k -b
    以wang sudo至mage用户执行ping存活检测
        ansible all -m ping -u wang -k -b --become-user=mage
    以wang sudo至root用户执行ls
        ansible all -m command -u wang -a 'ls /root' -b --become-user=root -k -K  

ansible常用模块

● Command:在远程主机执行命令,默认模块,可忽略-m选项
    ansible srvs -m command -a 'service vsftpd start'
    ansible srvs -m command -a 'echo magedu |passwd --stdin wang'
    此命令不支持 $VARNAME < > | ; & 等,用shell模块实现
● Shell:和command相似,用shell执行命令
    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服务器上的脚本
    -a "/PATH/TO/SCRIPT_FILE"
    ansible websrvs -m script -a /data/f1.sh

#小笔记
#------------------------------------------------# 
ansible-doc -s command
ansible all -m command -a "ls /data"
ansible all -m command -a "creates=/etc/xxx ls /data"   #不存在就执行ls /data
ansible all -m command -a "removes=/etc/xxx ls /data"

ansible-doc -s shell
ansible all -m shell -a 'echo $HOSTNAME'                    
ansible all -m shell -a 'echo magedu | passwd --stdin wang'

vim /etc/ansible/ansible.cfg
    [defaults]
    module_name = shell         #修改默认模块,默认为command
    
ansible all -m script -a "/root/test.sh"
#------------------------------------------------# 

Copy:从主控端复制文件到远程主机
ansible srv -m copy -a "src=/root/f1.sh dest=/tmp/f2.sh
    owner=wang mode=600 backup=yes"
    如目标存在,默认覆盖,此处指定先备份
ansible srv -m copy -a "content='test content\n' dest=/tmp/f1.txt"
    指定内容,直接生成目标文件
Fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录
    ansible srv -m fetch -a 'src=/root/a.sh dest=/data/scripts'
File:设置文件属性
    ansible srv -m file -a "path=/root/a.sh owner=wang mode=755"
    ansible web -m file -a 'src=/app/testfile dest=/app/testfile-link
    state=link'

#小笔记
#------------------------------------------------# 
ansbile websrvs -m copy -a 'src=/etc/fstab dest=/data/ backup=yes'  #复制当前系统文件到其他主机
ansbile websrvs -m copy -a 'content="line1\nlin2\nlin3" dest=/data/test backup=yes' #创建一个文件内容=content
ansible websrvs -m fetch -a 'src=/var/log/messages dest=/data/'         #复制远程系统文件到本机
ansible websrvs -m file -a 'path=/data/fstab owner=wang mode=700'       #修改文件属性
ansible websrvs -m file -a 'src=/data/fstab path=/data/fstab.link state=link'   #远程文件创建软链接
ansible websrvs -m file -a 'path=/data/f1.txt state=touch'              #创建新文件
ansible websrvs -m file -a 'path=/data/f1.txt state=absent'             #删除文件
ansible websrvs -m file -a 'path=/data/ state=absent'                   #删除文件夹及里面内容
#------------------------------------------------# 

ansible常用模块
    unarchive:解包解压缩,有两种用法:
    1、将ansible主机上的压缩包在本地解压缩后传到远程主机上,设置copy=yes.
    2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
    常见参数:
        copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
        src:源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no
        dest:远程主机上的目标路径
        mode:设置解压缩后的文件权限
    示例:
    ansible srv -m unarchive -a 'src=foo.tgz dest=/var/lib/foo'
    ansible srv -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777'
    ansible srv -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'

#小笔记
#------------------------------------------------# 
ansible websrvs -a unarchive -a 'src=/data/sysconfig.tar.gz dest=/data owner=wang mode=0700 copy=yes'
#------------------------------------------------# 

Archive:打包压缩
    ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=wang mode=0777'
Hostname:管理主机名
    ansible node1 -m hostname -a "name=websrv"
Cron:计划任务
    支持时间:minute,hour,day,month,weekday
    ansible srv -m cron -a "minute=*/5 job='/usr/sbin/ntpdate
    172.16.0.1 &>/dev/null' name=Synctime" 创建任务
    ansible srv -m cron -a 'state=absent name=Synctime' 删除任务
Yum:管理包
    ansible srv -m yum -a 'name=httpd state=present' 安装
    ansible srv -m yum -a 'name=httpd state=absent' 删除

#小笔记
#------------------------------------------------# 
#压缩
ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=wang mode=0777'
#改主机名
ansible 192.168.37.27 -m hostname -a "name=centos7-2"   
#创建计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime"
#禁用计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime disabled=yes"
#启动计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime disabled=no"
#删除计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime state=absent"

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 srv -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
    ansible srv -m user -a 'name=sysuser1 system=yes home=/app/sysuser1 '
    ansible srv -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"

#小笔记
#------------------------------------------------# 
#服务
ansible websrvs -m service -a 'name=httpd state=started'
ansible websrvs -m service -a 'name=httpd state=stopped'
#用户
ansible websrvs -m user -a 'name=mysql system=yes home=/data/mysql shell=/bin/false create_home=no'
ansible websrvs -m user -a 'name=mysql state=absent remove=yes'     #remove删除家目录
#------------------------------------------------# 

ansible系列命令

ansible-galaxy
    连接 https://galaxy.ansible.com 下载相应的roles
    列出所有已安装的galaxy
        ansible-galaxy list
    安装galaxy
        ansible-galaxy install geerlingguy.redis
    删除galaxy
        ansible-galaxy remove geerlingguy.redis

#小笔记
#------------------------------------------------# 
ansible-galaxy install geerlingguy.ntp
cd /root/.ansible/roles/geerlingguy.ntp
cat tasks/main.yaml
ansible-galaxy list
cp -r /root/.ansible/roles/geerlingguy.ntp /root/.ansible/roles/wang.app    #新角色
#------------------------------------------------# 

ansible-pull
    推送命令至远程,效率无限提升,对运维要求较高
ansible-playbook
    执行playbook
    示例:ansible-playbook hello.yml
    cat hello.yml
      #hello world yml file
        - hosts: websrvs
          remote_user: root
            tasks:
              - name: hello world
                command: /usr/bin/wall hello world

#------------------------------------------------# 
mkdir /data/playbook
cd /data/playbook
vim hello.yaml
- hosts: websrvs
  tasks:
    - name: first yml
      command: /bin/echo "hello world"
#------------------------------------------------# 
ansible-vault
    功能:管理加密解密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 创建新文件  
    
Ansible-console:2.0+新增,可交互执行命令,支持tab
    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    

playbook

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

YAML介绍

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

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语法

● YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构
(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,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  

三种常见的数据交换格式

image.png

Playbook核心元素

● Hosts 执行的远程主机列表
● Tasks 任务集
● Variables 内置变量或自定义变量在playbook中调用
● Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
● Handlers 和 notity 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
● tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。 ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
    ansible-playbook -t tagsname useradd.yml 

playbook基础组件

Hosts:
    ● playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份       执行任务。 hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
    ● 可以是如下形式:
        one.example.com
        one.example.com:two.example.com
        192.168.1.50
        192.168.1.*
    Websrvs:dbsrvs 或者,两个组的并集
    Websrvs:&dbsrvs 与,两个组的交集
    webservers:!phoenix 在websrvs组,但不在dbsrvs组
        示例: - hosts: websrvs:dbsrvs
        
● remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
    - hosts: websrvs
      remote_user: root
    tasks:
    - name: test connection
      ping:
      remote_user: magedu
      sudo: yes 默认sudo为root
      sudo_user:wang sudo为wang
      
● task列表和action
    play的主体部分是task list,task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务
    task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
    每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出 
    
● tasks:任务列表
● 两种格式:
    (1) action: module arguments
    (2) module: arguments 建议使用
    注意:shell和command模块后面跟命令,而非key=value
● 某任务的状态在运行后为changed时,可通过“notify” 通知给相应的handlers
● 任务可以通过"tags“打标签,可在ansible-playbook命令上使用-t指定进行调用
    示例:
      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

● 运行playbook的方式
    ansible-playbook  ... [options]
● 常见选项
    --check -C 只检测可能会发生的改变,但不真正执行操作
    --list-hosts 列出运行任务的主机
    --list-tags 列出tag
    --list-tasks 列出task
    --limit 主机列表 只针对主机列表中的主机执行
    -v -vv -vvv 显示过程
● 示例
    ansible-playbook file.yml --check 只检测
    ansible-playbook file.yml
    ansible-playbook file.yml --limit websrvs

Playbook VS ShellScripts

● 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
- name: "复制配置文件"
copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
- name: "复制配置文件"
copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.cd/
- name: "启动Apache,并设置开机启动"
service: name=httpd state=started enabled=yes

小笔记:编写httpd.yml文件

先安装httpd

yum install httpd -y

cp /etc/httpd/conf/httpd.conf /data/playbook/

vim /data/playbook/httpd.yml

---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: install
      yum: name=httpd
    - name: config
      copy: src=/data/playbook/httpd.conf dest=/etc/httpd/conf/
    - name: service
      service: name=httpd state=started enabled=yes
#检查
ansible-playbook -C httpd.yml
#执行
ansible-playbook httpd.yml

小笔记:编写install_mysql.yml文件

vim /data/playbook/install_mysql.yml

---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: user
      user: name=mysql systemctl=yes home=/data/mysql create_home=no shell=/sbin/nologin
    - name: unarchive
      unarchive: src=/data/playbook/mariadb-10.2.25-linux-x86_64.tar.gz dest=/usr/local owner=root group=root
    - name: mysql link
      file: src=/usr/local/mariadb-10.2.25-linux-x86_64 dest=/usr/local/mysql state=link
    - name: mysql datadir
      file: path=/data/mysql state=directory
    - name: mysql datadir owner group
      file: path=/data/mysql owner=mysql group=mysql
    - name: mysql database
      shell: chdir=/usr/local/mysql/ scripts/mysql_install_db --datadir=/data/mysql --user=mysql
    - name: path var
      copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
    - name: config
      copy: src=/data/playbook/my-huge.cnf dest=/etc/my.cnf
    - name: service file
      shell: cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
    - name: start file
      shell: /etc/init.d/mysqld start

#检查
ansible-playbook -C install_mysql.yml
#执行
ansible-playbook install_mysql.yml

示例 sysuser.yml

- 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.yml

- 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

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
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

小笔记:httpd.yml改进

---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: install
      yum: name=httpd
    - name: config
      copy: src=/data/playbook/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd
    - name: service
      service: name=httpd state=started enabled=yes
      
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted      

示例

- 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使用

示例:httpd.yml
- 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/
      tags: conf
    - name: start httpd service
      tags: service
      service: name=httpd state=started enabled=yes

ansible-playbook -t conf httpd.yml

小笔记:httpd.yml使用tags

---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: install
      yum: name=httpd
    - name: config
      copy: src=/data/playbook/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd
      tags;conf
    - name: service
      service: name=httpd state=started enabled=yes
      tags: service
      
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

ansible-playbook --list-tags httpd.yml
ansible-playbook -t conf httpd.yml     

Playbook中变量使用

变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
    1 ansible setup facts 远程主机的所有变量都可直接调用
    2 在/etc/ansible/hosts中定义
        普通变量:主机组中主机单独定义,优先级高于公共变量
        公共(组)变量:针对主机组中所有主机定义统一变量
    3 通过命令行指定变量,优先级最高
        ansible-playbook –e varname=value
    4 在playbook中定义
        vars:
            - var1: value1
            - var2: value2
    5 在独立的变量YAML文件中定义
    6 在role中定义

Playbook中变量使用
    变量命名
        变量名仅能由字母、数字和下划线组成,且只能以字母开头
    变量定义:key=value
        示例:http_port=80
    变量调用方式:
        通过{{ variable_name }} 调用变量,且变量名前后必须有空格,有时用“{{ variable_name }}”才生效
        ansible-playbook –e 选项指定
            ansible-playbook test.yml -e "hosts=www user=magedu"

#小笔记
#-----------------分割线--------------------#
#查看变量
ansible 192.168.37.17 -m setup      #查看主机信息
ansible 192.168.37.17 -m setup -a 'filter=ansible_nodename'         #查看主机名
ansible 192.168.37.17 -m setup -a 'filter=ansible_memtotal_mb'      #查看主机物理内存
ansible 192.168.37.17 -m setup -a 'filter=ansible_*total*'          #查看主机物理及虚拟内存
ansible 192.168.37.17 -m setup -a 'ansible_distribution_major_version'  #查看系统主版本

#声明变量
vim /etc/ansible/hosts
    [websrvs]
    192.168.37.6 hostname=node1
    192.168.37.17 hostname=node2
    
#定义变量
vim /etc/ansible/hosts
    [websrvs:vars]
    suf=txt
    
#在playbook文件中定义变量,参考var2.yml

#命令模式定义命令
ansible-playbook -e hostname=file -e suf=pdf vars2.yml      #-e优先级高 > yml文件 > hosts文件

#单文件专门放变量
vim vars.yml
hostname: testnode
suf: xml
:wq

var.yml

---
  - hosts: websrvs
  
  tasks:
    - name: create file
      file: name=/data/{{ansible_nodename}}.log state=touch
      #file: name=/data/{{ansible_nodename}}.{{suf}} state=touch

var2.yml

---
  - hosts: websrvs
    vars:
      - hostname:testfile
      - suf: html
  tasks:
    - name: create file
      file: name=/data/{{ansible_nodename}}.{{suf}} state=touch

var3.yaml

---
  - hosts: websrvs
    vars: vars.yml
    
  tasks:
    - name: create file
      file: name=/data/{{ansible_nodename}}.{{suf}} state=touch

模板template

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

ansible-doc template

template功能:根据模块文件动态生成对应的配置文件
    template文件必须存放于templates目录下,且命名为 .j2 结尾
    yaml/yml 文件需和templates目录平级,目录结构如下:
        ./
            ├── temnginx.yml
            └── templates
                └── nginx.conf.j2

小笔记:httpd模板

#ansible服务器修改httpd.conf
cd /data/playbook
mkdir template
cp /etc/httpd.conf template/httpd.conf.j2
vim template/httpd.conf.j2
    listen {{ httpd_port }}
:wq
vim httpd_template.yml
---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: install
      yum: name=httpd
    - name: config
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      notify: restart httpd
      tags;conf
    - name: service
      service: name=httpd state=started enabled=yes
      tags: service
      
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted
:wq
vim /etc/ansible/hosts
    [appsrvs]
    192.168.37.17 httpd_port=8017
    192.168.37.27 httpd_port=8027

#测试
ansible-playbook -C httpd_template.yml 
ansbile-playbook httpd_template.yml

小笔记:nginx模板

cp /etc/nginx/nginx.conf /data/playbook/templates/nginx.conf.j2
cd /data/playbook
vim nginx.yml
---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: install
      yum: name=nginx
    - name: config
      temlplate:src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
    - name: install
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted
:wq
vim templates/nginx.conf.j2
    worker_processes {{ ansbile_processor_vcpus*2 }}
:wq

#测试
ansible-playbook -C nginx.yml
ansbile-playbook nginx.yml

when

● 条件测试:如果需要根据变量、 facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法格式
● when语句
    在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法
● 示例:
    tasks:
      - name: "shutdown RedHat flavored systems"
        command: /sbin/shutdown -h now
        when: ansible_os_family == "RedHat" 

小笔记:httpd2.2与2.4配置模板

由于httpd2.2(centos6)与2.4(centos7)的配置文件不通用,故分开2个模板

#准备好2文件并放在template目录下
#文件名:httpd6.conf.j2,httpd7.conf.j2
cd /data/playbook
vim httpd_when.yml
---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: install
      yum: name=httpd
    - name: config
      template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
      tags: conf
      notify: restart httpd
      when: ansible_distribution_major_version=="6" 
    - name: config
      template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf
      tags: conf
      notify: restart httpd
      when: ansible_distribution_major_version=="7"   
    - name: service
      service: name=httpd state=started enabled=yes
      tags: service
      
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

vim /etc/ansible/hosts
    [websrvs]
    192.168.37.17 httpd_port=6666
    192.168.37.27 httpd_port=7777

#测试
ansible-playbook -C httpd_when
ansbile-playbook httpd_when

迭代:with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制
    对迭代项的引用,固定变量名为” item“
    要在task中使用with_items给定要迭代的元素列表
    列表格式:
        字符串
        字典  

例如:
vim useradd.yml
---
- hosts: websrvs

  tasks:
  - name: create user
  user: name={{ item }} #remove=yes     #remove删除账户
  with_items:
    - tom
    - alice
    - jack
    - rose
    
示例:迭代嵌套子变量
- hosts:websrvs
  remote_user: root
  tasks:
    - name: add some groups
      group: name={{ item }} state=present
      with_items:
        - group1
        - group2
        - group3
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'user1', group: 'group1' }
        - { name: 'user2', group: 'group2' }
        - { name: 'user3', group: 'group3' }  

Playbook中template for if

{% for vhost in nginx_vhosts %}

server {
listen {{ vhost.listen | default('80 default_server') }};

{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }};
{% endif %}

{% if vhost.root is defined %}
root {{ vhost.root }};
{% endif %}

{% endfor %} 

例子:
vim for.yml
- hosts: appsrvs
  var:
    port:
      - web1:
        listen_port:81
        name: web1.magedu.com
        dir: /data/web1
      - web2:
        listen_port:82
        name: web2.magedu.com
        dir: /data/web2
      - web3:
        listen_port:83
        name: web3.magedu.com
        dir: /data/web3  
    tasks:
      - name: config
        template: src=server.conf.j2 dest=/data/server.conf
:wq

vim server.conf.j2
{%for port in ports %}
server{
    listen {{port.listen_port}}
{% if port.name is defined %}    
    server_name {{port.name}}
{%endif%}    
    root {{port.dir}}
}
{%endfor%}
:wq

#测试
ansible-playbook -C httpd_when
ansbile-playbook httpd_when

#查看结果
cat /data/server.conf

示例1

// temnginx.yml
---
  - hosts: testweb
  remote_user: root
  vars:
    nginx_vhosts:
    - listen: 8080

//templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
    listen {{ vhost.listen }}
}
{% endfor %}

#生成的结果
server {
    listen 8080
}

示例2

// temnginx.yml
---
  - hosts: mageduweb
    remote_user: root
    vars:
      nginx_vhosts:
        - web1
        - web2
        - web3
  tasks:
    - name: template config
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

// templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
    listen {{ vhost }}
}
{% endfor %}

#生成的结果:
server {
    listen web1
}
server {
    listen web2
}
server {
    listen web3
}

示例3

// temnginx.yml
- hosts: mageduweb
  remote_user: root
  vars:
    nginx_vhosts:
      - web1:
        listen: 8080
        server_name: "web1.magedu.com"
        root: "/var/www/nginx/web1/"
      - web2:
        listen: 8080
        server_name: "web2.magedu.com"
        root: "/var/www/nginx/web2/"
      - web3:
        listen: 8080
        server_name: "web3.magedu.com"
        root: "/var/www/nginx/web3/“
  tasks:
    - name: template config
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      
// templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
    listen {{ vhost.listen }}
    server_name {{ vhost.server_name }}
    root {{ vhost.root }}
}
{% endfor %}

#生成结果:
server {
    listen 8080
    server_name web1.magedu.com
    root /var/www/nginx/web1/
}
server {
    listen 8080
    server_name web2.magedu.com
    root /var/www/nginx/web2/
}
server {
    listen 8080
    server_name web3.magedu.com
    root /var/www/nginx/web3/
}

示例4

// temnginx.yml
- hosts: mageduweb
  remote_user: root
  vars:
    nginx_vhosts:
    - web1:
      listen: 8080
      root: "/var/www/nginx/web1/"
    - web2:
      listen: 8080
      server_name: "web2.magedu.com"
      root: "/var/www/nginx/web2/"
    - web3:
      listen: 8080
      server_name: "web3.magedu.com"
      root: "/var/www/nginx/web3/"
  tasks:
    - name: template config to
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
    
// templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost.listen }}
{% if vhost.server_name is defined %}
  server_name {{ vhost.server_name }}
{% endif %}
  root {{ vhost.root }}
}
{% endfor %}

#生成的结果
server {
  listen 8080
  root /var/www/nginx/web1/
}
server {
    listen 8080
    server_name web2.magedu.com
    root /var/www/nginx/web2/
}
server {
    listen 8080
    server_name web3.magedu.com
    root /var/www/nginx/web3/
}

Roles

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

Ansible Roles目录编排

image.png

roles目录结构

每个角色,以特定的层级目录结构进行组织
roles目录结构:
    playbook.yml
    roles/
      project/
        tasks/
        files/
        vars/
        templates/
        handlers/
        default/ 不常用
        meta/ 不常用

Roles各目录作用

/roles/project/ :项目名称,有以下子目录
    files/ :存放由copy或script模块等调用的文件
    templates/:template模块查找所需要模板文件的目录
    tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    vars/:定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
    meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
    default/:设定默认变量时使用此目录中的main.yml文件

针对大型项目使用Roles进行编排

roles目录结构:
playbook.yml
roles/
  project/
    tasks/
    files/
    vars/
    templates/
    handlers/
    default/ # 不经常用     
    meta/ # 不经常用
    
示例:
    nginx-role.yml
    roles/
    └── nginx
        ├── files
        │ └── main.yml
        ├── tasks
        │ ├── groupadd.ym
        │ ├── install.yml
        │ ├── main.yml
        │ ├── restart.yml
        │ └── useradd.yml
        └── vars
            └── main.yml    

小笔记:创建nginx-roles目录结构

cd /data/playbook
mkdir -p roles/nginx/{tasks,files}
cd  roles/nginx/tasks
touch user.yml install.yml config.yml data.yml serivce.yml
vim user.yml
- name: create user
  user: name=nginx shell=/sbin/nologin system=yes create_home=no
:wq
vim install.yml
- name: install
  yum: name=nginx
:wq
cp /etc/nginx/nginx.conf ../roles/nginx/files/
vim ../roles/nginx/files/nginx.conf
    listen  9527
    listen  [::]:9527
:wq
mkdir -p ../handlers 
vim ../handlers/main.yml
- name: restart service
  service: name=nginx state=restarted
:wq
vim config.yml
- name: config
  copy: src=nginx.conf dest=/etc/nginx/nginx.conf
  notify: restart service
:wq
vim service.yml
- name: service
  service: name=nginx state=started enabled=yes
:wq
echo "wlecome to magedu" > ../files/index.html
vim data.yml
- name: data
  copy: src=index.html dest=/usr/share/nginx/html
:wq
vim main.yml
- include: user.yml 
- include: install.yml 
- include: config.yml 
- include: data.yml
- include: serivce.yml
:wq
cd /data/playbook
vim nginx_role.yml
- hosts: appsrvs
  roles:
    - role: nginx
:wq

#测试
ansible-playbook -C nginx_role.yml
ansible-playbook nginx_role.yml

小笔记:创建apache-roles 目录结构

cd /data/playbook/roles
mkdir -p httpd/{tasks,files,template,vars,handlers}
cd httpd/tasks
touch user.yml install.yml config.yml data.yml service.yml
ls > main.yml
vim ../handlers/main.yml
- name: restart service
  service: name=httpd state=restarted
:wq
vim install.yml
- name: install
  yum: name=httpd
:wq
cp /etc/httpd/conf/httpd.conf ../templates/httpd.conf.j2
vim ../templates/httpd.conf.j2
    listen {{ httpd_port }}
    User {{ username }}
    Group {{ groupname }}
:wq
vim ../vars/main.yml
httpd_port: 80
username: daemon
groupname: daemon
:wq
vim config.yml
- name: config
  copy: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  notify: restart service
:wq
vim data.yml
- name: data file
  copy: src=roles/nginx/files/index.html dest=/var/www/html/
:wq
vim service.yml
- name: service
  service: name=httpd state=started enabled=yes
:wq
vim main.yml
- include: install.yml
- include: config.yml
- include: data.yml
- include: service.yml
:wq
cd /data/playbook
vim httpd_role.yml
- hosts: appsrvs
  roles:
    - httpd
:wq

#测试
ansible-playbook -C httpd_role.yml
ansible-playbook httpd_role.yml

小笔记:创建mysql-roles 目录结构

cd /data/playbook/roles
mkdir mysql/{tasks,files,handlers}
cd mysql/tasks
touch user.yml unarchive.yml link.yml datadir.yml database.yml var.yml config.yml script.yml service.yml
cat > user.yml < unarchive.yml < link.yml < datadir.yml < database.yml < var.yml < config.yml < script.yml < service.yml < main.yml < ../handlers/main.yml < mysql_role.yml <

按版本安装

  • 注意软件版本,版本不用配置文件不通用

vim /data/playbook/httpd_nginx_roles.yml

- hosts: all

  roles:

    - {role: httpd, when: ansible_distribution_major_version=="6"}
    - {role: nginx, when: ansible_distribution_major_version=="7"}

标签使用

- hosts: all
  
  roles:
    - {role: httpd, when: ansible_distribution_major_version=="6", tags: ["web","httpd"]}
    - {role: nginx, when: ansible_distribution_major_version=="7", tags: ["web","nginx"]}

创建 memcached 目录结构

yum install memcached
cd /data/playbook
mkdir -p roles/memcached/{tasks,files,templates,handlers}
cd roles/memcached
cp /etc/sysconfig/memcached templates/memcached.j2
vim templates/memcached.j2
PROT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ansible_memtotal_mb//4}}"      #//取整
OPTIONS=""
:wq
cd tasks
touch install.yml config.yml service.yml
cat > install.yml < config.yml < service.yml < main.yml < ../handlers/main.yml < mysql_role.yml <

推荐资料

● http://galaxy.ansible.com
● https://galaxy.ansible.com/explore#/
● http://github.com/
● http://ansible.com.cn/
● https://github.com/ansible/ansible
● https://github.com/ansible/ansible-examples  

你可能感兴趣的:(24-运维自动化之ANSIBLE)