Ansible自动化运维

Ansible自动化运维

  • 一:Ansible概述
  • 二:常用自动化运维工具
  • 三:安装准备
    • 3.1 环境准备
    • 3.2 安装
    • 3.3 Ansible配置文件
    • 3.4 Ansible-doc
    • 3.5 Ansible命令参数
  • 四:主机清单(inventory)
    • 4.1 基于密码管控主机
    • 4.2 基于密钥管控主机
    • 4.3 主机匹配
    • 4.4 Ansible命令执行过程
  • 五:常见模块实战
    • 5.1 command模块
    • 5.2 shell模块
    • 5.3 scripts模块
    • 5.4 copy模块
    • 5.5 fetch模块
    • 5.6 file模块
    • 5.7 hostname模块
    • 5.8 cron模块
    • 5.9 yum模块
    • 5.10 stat模块
    • 5.11 get_url模块
    • 5.12 service模块
    • 5.13 sysctl模块
    • 5.14 user模块
  • 六:ansible-galaxy
  • 七:playbook
    • 7.1 ansible-vault
    • 7.2 ansible-console
    • 7.3 使用playbook
    • 7.4 handlers和notify结合使用触发条件
    • 7.5 tags使用
    • 7.6 playbook中使用变量
    • 7.7 使用template
    • 7.8 for循环
    • 7.9 when
    • 7.10 with_items
  • 八:roles

一:Ansible概述

Ansible(官方文档,中文文档)是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python写成,类似于saltstack和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。Ansible基于 Python paramiko 开发,分布式,无需客户端,轻量级,配置语法使用 YMAL 及 Jinja2模板语言,更强的远程命令执行操作

ansiblle具有如下特点:

  1. 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
  2. 默认使用SSH协议对设备进行管理;
  3. 主从集中化管理;
  4. 配置简单、功能强大、扩展性强;
  5. 支持API及自定义模块,可通过Python轻松扩展;
  6. 通过Playbooks来定制强大的配置、状态管理
  7. 对云计算平台、大数据都有很好的支持;

ansible整体架构如下:
Ansible自动化运维_第1张图片
注意事项:

  1. 执行ansible的主机一般称为主控端,中控,master或堡垒机
  2. 主控端Python版本需要2.6或以上
  3. 被控端python版本小于2.4需要安装python-simplejson
  4. 被控端如开启selinux需要安装libselinux-python
  5. windows不能作为主控端

二:常用自动化运维工具

  1. Asible:python, Agentless,中小型应用环境
  2. Saltstack:python,一般需要部署agent,执行效率更高
  3. Puppet:rubby,功能强大,配置复杂,重型,适合大型环境
  4. Fabric:python,agentless
  5. Chef:rubby,国内应用很少
  6. Cfengine
  7. func

三:安装准备

3.1 环境准备

IP System Hostname Role
172.17.2.245 CentOS7.4 node245.ginvip.com master
172.17.2.246 CentOS7.4 node246.ginvip.com slaver
172.17.2.247 CentOS7.4 node247.ginvip.com slaver
172.17.2.248 CentOS7.4 node248.ginvip.com slaver

3.2 安装

Ansible仓库默认不在yum仓库中,因此我们需要使用下面的命令安装epel仓库。

# master端安装即可
yum install epel-release -y
yum install ansible -y 
ansible --version

pip方式安装:

yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-build openssl-devl
pip install --upgrade pip
pip install ansible --upgrade

配置文件:

/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界面与用户交互的执行工具

3.3 Ansible配置文件

Ansible默认安装好后有一个配置文件/etc/ansible/ansible.cfg,该配置文件中定义了ansible的主机的默认配置部分,如默认是否需要输入密码、是否开启sudo认证、action_plugins插件的位置、hosts主机组的位置、是否开启log功能、默认端口、key文件位置等等。

[defaults]
    # some basic default values...
    # hostfile       = /etc/ansible/hosts   	# 指定默认hosts配置的位置
    # library_path = /usr/share/my_modules/
    # remote_tmp     = $HOME/.ansible/tmp
    # pattern        = *
    # forks          = 5						# 默认并发数
    # poll_interval  = 15
    # sudo_user      = root  					# 远程sudo用户
    # ask_sudo_pass = True  					# 每次执行ansible命令是否询问ssh密码
    # ask_pass      = True  					# 每次执行ansible命令时是否询问sudo密码
    # transport      = smart
    # remote_port    = 22
    # module_lang    = C
    # gathering = implicit
    host_key_checking = False    				# 检查对应服务器的host_key,建议取消注释
    log_path    = /var/log/ansible.log 			# 需要时可以自行添加。chown -R root:root ansible.log
	# 一般只修改上面两项配置,其他的无需修改

3.4 Ansible-doc

ansible-doc:显示模块帮助

ansible-doc [options] [module...]
-a:显示所有模块的文档
-l, --list:列表可用模块
-s, --snippet:显示指定模块的playbook片段
ansible-doc ping		# 查看ping模块的使用说明
ansible-doc -s ping		# 简洁版ping模块的使用说明

3.5 Ansible命令参数

anisble命令语法: ansible [-i 主机文件] [-f 批次] [组名] [-m 模块名称] [-a 模块参数]

ansible详细参数:

-v,–verbose                   #  详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv)
-i PATH, -inventory=PATH      #  指定 host 文件的路径,默认是在 /etc/ansible/hosts ,inventory  [ˈɪnvəntri]  库存
-f NUM,-forks=NUM             #  NUM 是指定一个整数,默认是 5 ,指定 fork 开启同步进程的个数。
-m NAME,-module-name=NAME     #   指定使用的 module 名称,默认使用 command模块
-a,MODULE_ARGS                # 指定 module 模块的参数
-k,-ask-pass                  # 提示输入 ssh 的密码,而不是使用基于 ssh 的密钥认证
-sudo                         # 指定使用 sudo 获得 root 权限
-K,-ask-sudo-pass             # 提示输入 sudo 密码,与 -sudo 一起使用
-u USERNAME,-user=USERNAME    # 指定移动端的执行用户
-C,–check                    # 测试此命令执行会改变什么内容,不会真正的去执行
-b,--become                 # 代替旧版的sudo切换
ansible dbservers -m command -a 'ls -l /root' -u ubuntu -k -b -K   # 以root身份执行
ansible all --list            	# 查看inventory列表
ansible webservers --list    	# 查看某个分组下inventory

四:主机清单(inventory)

4.1 基于密码管控主机

在/etc/ansible/hosts文件中加入要管理的主机:

[root@node245 ~]# tail -1 /etc/ansible/hosts 
172.17.2.24[6:8]

使用ping模块检测远程主机是否存活:

[root@node245 ~]# ansible 172.17.2.247,172.17.2.248 -m ping -k
SSH password: 
172.17.2.248 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
# ansible只会输入一次密码,即这一个密码会自动去匹配所有的主机
# -k 使用密码登录远程主机
# -m 指定使用哪个ansible模块
# 也可以将上面的IP地址换成 all 代表检测清单中的所有主机

在/etc/ansible/hosts文件中配置远程主机密码:

[root@node245 ~]# tail -3 /etc/ansible/hosts 
172.17.2.246 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=root
172.17.2.247 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=root
172.17.2.248 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=root
ansible all -m ping		# 检测清单中所有主机,因为清单文件中配置了SSH登录信息,所以这里就不再提示要输入密码

在/etc/ansible/hosts文件中配置主机分组:

[root@node245 ~]# tail -10 /etc/ansible/hosts 
[webservers]
172.17.2.246
172.17.2.247

[dbservers]
172.17.2.247
172.17.2.248

[appservers]
172.17.2.24[6:8]

这样在执行ansible命令时就可以指定分组:

ansible appservers -m ping -k

4.2 基于密钥管控主机

一般来说,使用明文密码不安全,所以增加主机无密码访问。在Ansible服务端生成密钥,并且复制公钥到节点中。

ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
for i in {0..2}; do ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.17.2.24${i}; done

测试所有主机连通性:

ansible appservers -m ping		# 此时就不再需要输入密码

4.3 主机匹配

ansible all -m ping                        # 所有
ansible 172.17.2.* -m ping                 # 通配符
ansible webservers:dbservers -m ping       # 或关系
ansible 'webservers:&dbservers' -m ping    # 且关系。注意清单列表要加上引号(单双都可),因为&符在linux下表示后台执行
ansible 'webservers:!dbservers' -m ping    # 非关系。在webservers但不在dbservers中。(因为有!号,所有只参使用单引号)
ansible '~(web|db)servers' -m ping         # 正则表达式,~表示包含

4.4 Ansible命令执行过程

ansible命令执行过程:

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

执行状态:

  1. 绿色:执行成功并且不需要做改变的操作
  2. 黄色:执行成功并且对目标主机做变更
  3. 红色:执行失败
ansible all -m ping -vvv     # 加-v或-vv或-vvv参数查看命令执行过程

五:常见模块实战

5.1 command模块

command模块执行shell命令,command作为ansible的默认模块,可以运行远程权限范围内的所有shell命令

ansible webservers -m ping       # 默认模块为command,可省略
ansible webservers -a 'removes=/etc/fs cat /etc/fstab'
# removes表示后面的文件不存在,则不执行后面的命令
ansible webservers -a 'creates=/etc/fs cat /etc/fstab'
# creates表示后面的文件存在,则不执行后面的命令
ansible webservers -a 'chdir=/boot cat /etc/fstab'    # chdir切换到指定目录下执行后面的命令

comand模块比较简单,常见的命令都可以使用,但其命令的执行不是通过shell执行的,所以,像这些 “<”, “>”, “|”, and "&"操作都不可以,当然,也就不支持管道; 缺点:不支持管道,没法批量执行命令

5.2 shell模块

使用shell模块,在远程命令通过/bin/sh来执行;所以,我们在终端输入的各种命令方式,都可以使用。

ansible webservers -m shell -a "useradd test"
ansible webservers -m shell -a "echo test|passwd --stdin test"
ansible webservers -m shell -a "source  ~/.bash_profile && df -h | grep sda" 

对shell模块的使用可以分成两块:

  1. 如果待执行的语句少,可以直接写在一句话中
  2. 如果在远程待执行的语句比较多,可写成一个脚本,通过copy模块传到远端,然后再执行;但这样就又涉及到两次ansible调用;对于这种需求,ansible已经为我们考虑到了,script模块就是干这事的;

5.3 scripts模块

使用scripts模块可以在本地写一个脚本,在远程服务器上执行,(不需要手动上传脚本到指定服务器)

ansible all -m script -a '/root/ansible/host.sh'

5.4 copy模块

实现主控端向目标主机拷贝文件,类似scp功能

ansible all -m copy -a "src=/root/ansible/selinux dest=/etc/selinux/config backup=yes"
# 如果目标存在,默认覆盖;backup=yes 覆盖前先备份
ansible webservers -m copy -a "content='test content\n' dest=/tmp/f1.txt"
# 利用内容,直接生成目标文件

5.5 fetch模块

Fetch files from remote nodes(不能拉到目录)

ansible all -m fetch -a "src=/var/log/messages dest=/backup"
ansible all -m shell -a "tar Jcf /root/tools.tar.xz /root/tools"    # 打包文件

5.6 file模块

设置文件属性

ansible all -m file -a 'name=/root/f3 state=touch'          # 创建文件
ansible all -m file -a 'name=/root/f3 state=absent'         # 删除文件或目录,软链接
ansible all -m file -a 'name=/root/dir1 state=directory'    # 创建目录
ansible all -m file -a 'src=/etc/fstab path=/root/fstab.link state=link'    # 创建软链接
ansible all -m file -a 'path=/root/f3 owner=ginvip mode=755' # 修改文件权限

5.7 hostname模块

hostname模块执行后会修改/etc/hostname文件,且立即生效。但不会修改/etc/hosts文件

ansible 172.17.2.241 -m hostname -a "name=node08.ginvip.com"

5.8 cron模块

远程主机crontab配置。

ansible webservers -m cron -a "minute=* weekday=1,3,4 job='/usr/bin/wall warning' name=warningcron"
ansible webservers -m cron -a "disabled=true job='/usr/bin/wall warning' name=warningcron"
# 禁用定时任务,job,name都需要指定(本质上是在定时任务文件中注释了该条命令)
ansible webservers -m cron -a "disabled=false job='/usr/bin/wall warning' name=warningcron"
# 重新启动定时任务
ansible webservers -m cron -a "job='/usr/bin/wall warning' name=warningcron state=absent"
# 删除计划任务

5.9 yum模块

linux平台软件包管理。yum模块可以提供的status状态: latest ,present,installed #这3个代表安装;removed, absent #这2个是卸载

ansible webservers -m yum -a "name=httpd  state=latest"    # 安装
ansible webservers -m yum -a "name=httpd,httpd,memcached  state=latest"    # 安装多个
ansible webservers -m yum -a "name=httpd  state=absent"    # 卸载

5.10 stat模块

获取远程文件信息

ansible -i /etc/ansible/hosts webservers -m stat -a "path=/tmp/hosts"

5.11 get_url模块

实现远程主机下载指定url到本地,支持sha256sum文件校验。
例如:下载epel-release-latest-7.noarch.rpm到主机清单中的/tmp/目录下

ansible -i /etc/ansible/hosts webservers -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm  dest=/tmp/ mode=0440 force=yes"

注:url=https://xxx 的等号=前后不能有空格
扩展:查看force=yes的作用

ansible-doc -s get_url  #在弹出的信息中找到force

如果force=yes,当下载文件时,如果所下的内容和原目录下的文件内容不一样,则替换原文件,如果一样,就不下载了。
如果为“否”,则仅在目标不存在时才下载文件。 一般来说,只有小型本地文件才应该为“是”。 在0.6之前,该模块表现为默认为“是”。
查看下载的文件:

ll /tmp/epel-release-latest-7.noarch.rpm 
-r--r----- 1 root root 15080 824 16:20 /tmp/epel-release-latest-7.noarch.rpm 

测试:下载文件时,当文件不一样时,会替换原来的文件

[root@node245 ~]# cp /etc/passwd /tmp/epel-release-latest-7.noarch.rpm
[root@node246 ~]# ansible -i /etc/ansible/hosts webservers -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm  dest=/tmp/ mode=0440 force=yes"
172.17.2.245 | SUCCESS => {
    "changed": false,   # 原来的文件和当前的文件一样,就没有改变。执行成功,但没有发生改变,那么显示绿色
   。。。
}
172.17.2.246 | SUCCESS => {
    "changed": true,   # 文件名字一样,但是内容变,就会重新下载。执行成功,且发生改变,那么显示黄色

5.12 service模块

远程主机系统服务管理。
service模块常用参数:
(1)、name参数:此参数用于指定需要操作的服务名称,比如 nginx,httpd。
(2)、state参数:此参数用于指定服务的状态,比如,我们想要启动远程主机中的httpd,则可以将 state 的值设置为 started;如果想要停止远程主机中的服务,则可以将 state 的值设置为 stopped。此参数的可用值有 started、stopped、restarted(重启)、reloaded。
enabled参数:此参数用于指定是否将服务设置为开机 启动项,设置为 yes 表示将对应服务设置为开机启动,设置为 no 表示不会开机启动。
注:想使用service模块启动服务,被启动的服务,必须可以使用service 命令启动或关闭

[root@node245 ~]# ansible webservers -m service -a "name=httpd state=restarted"

5.13 sysctl模块

远程主机sysctl配置。
例:开启路由转发功能

[root@node245 ~]# ansible -i /etc/ansible/hosts webservers -m sysctl -a "name=net.ipv4.ip_forward value=1 reload=yes"

验证:

[root@node245 ~]# cat /proc/sys/net/ipv4/ip_forward
1 

5.14 user模块

远程主机用户管理

[root@node245 ~]# ansible -i /etc/ansible/hosts webservers -m user -a "name=xuegod6 state=present"

六:ansible-galaxy

连接到https://galaxy.ansible.com下载相应的roles

[root@node245 ansible]# ansible-galaxy install geerlingguy.nginx
- downloading role 'nginx', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-nginx/archive/2.7.0.tar.gz
- extracting geerlingguy.nginx to /root/.ansible/roles/geerlingguy.nginx
- geerlingguy.nginx (2.7.0) was installed successfully

[root@node245 ansible]# ansible-galaxy list geerlingguy.nginx
# /root/.ansible/roles
- geerlingguy.nginx, 2.7.0

删除galaxy:

ansible-galaxy remove geerlingguy.nginx    # 直接删除目录也可

列出所有已安装的galaxy:

ansible-galaxy list

七:playbook

playbook实例:安装tomcat

[root@node245 ansible]# cat tomcat.yml
---                                 # 表明下面要写playbook。不写也可以
- hosts: tomcat
  remote_user: root                 # 以什么身份在远程主机上执行命令
  gather_facts: no
  vars:
    tomcat_version: 8.5.53
    tomcat_install_dir: /usr/local

  tasks:
    - name: install jdk1.8
      yum: name=java-1.8.0-openjdk state=present

    - name: download tomcat
      get_url: url=https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v{{ tomcat_version }}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz dest=/tmp validate_certs=no

    - name: unarchive tomcat-{{ tomcat_version }}.tar.gz
      unarchive:
        src: /tmp/apache-tomcat-{{ tomcat_version }}.tar.gz
        dest: "{{ tomcat_install_dir }}"
        copy: no

    - name: start tomcat
      shell: cd {{ tomcat_install_dir }} && mv apache-tomcat-{{ tomcat_version }} tomcat && cd tomcat/bin/ && nohup ./startup.sh &

执行playbook:

[root@node245 ansible]# ansible-playbook tomcat.yml 

7.1 ansible-vault

ansible-vault encrypt hello.yml    # 对文件进行加密(会要求输入密码)
ansible-vault view hello.yml       # 查看加密后的文件内容(真实内容)
ansible-vault edit hello.yml       # 编辑
ansible-vault rekey hello.yml      # 修改密码
ansible-vault decrypt hello.yml    # 解密

7.2 ansible-console

2.0+新增,可交互执行命令,支持tab

[root@node245 ansible]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.
# 执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]
root@all (3)[f:5]$ cd webservers           # 进入webservers清单
root@webservers (2)[f:5]$ forks 10         # 修改为10个并发
root@webservers (2)[f:10]$ command hostname       # 调用command模块执行hostname命令
root@webservers (2)[f:10]$ cd 172.17.2.241
root@172.17.2.241 (1)[f:10]$ hostname name=node03.ginvip.com

7.3 使用playbook

Ansible自动化运维_第2张图片
中文文档见:http://www.ansible.com.cn/
一个完整的代码块功能需最少元素包括 name: task
一个name只能包括一个task
YAML文件扩展名通常为yml或yaml

[root@node245 ansible]# cat file.yml 
---
- hosts: webservers
  remote_user: root

  tasks:
    - name: create new file
      file: name=/data/newfile state=touch
    - name: create new user
      user: name=test2 system=yes shell=/sbin/nologin
    - name: install packge
      yum: name=httpd
    - name: copy html
      copy: src=/var/www/html/index.html dest=/var/www/html
    - name: start service
      service: name=httpd state=started enabled=yes

执行playbook:

ansible-playbook -C file.yml     # -C check测试运行
ansible-playbook file.yml
ansible-playbook file.yml --limit 172.17.2.240   # 限制只在后面的IP主机上运行playbook
ansible-playbook file.yml --list-tasks   # 查看playbook中有几个任务
ansible-playbook file.yml --list-host    # 查看playbook中的主机

如果命令或脚本的即出码不为零(即playbook中有一行代码报错了)但又不想退出而是继续执行下面的操作,可以使用如下方式替代:

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

7.4 handlers和notify结合使用触发条件

handlers:是task列表,这些task与前述的task并没有本质上的区别,用于当关注的资源发生变化时才会采取一定的操作
notify:此action可用于在每个play的最后触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在nofity中列出的操作称为handler,也即notify中调用handler中定义的操作

[root@node245 ansible]# cat httpd.yml
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: install httpd package
      yum: name=httpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
      notify: restart service      # 当配置文件发生改变触发下面的handlers,重启httpd程序
    - name: copy html file
      copy: src=files/index.html dest=/var/www/html/
    - name: start service
      service: name=httpd state=started enabled=yes
  handlers:
    - name: restart service
      service: name=httpd state=restarted

7.5 tags使用

[root@node245 ansible]# cat httpd.yml
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: install httpd package
      yum: name=httpd
      tags: ihttpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
      notify: restart service
    - name: copy html file
      copy: src=files/index.html dest=/var/www/html/
    - name: start service
      service: name=httpd state=started enabled=yes
      tags: shttpd     # 定义tags
  handlers:
    - name: restart service
      service: name=httpd state=restarted

定义完tags后,在执行playbook时可以指定tags执行(只会执行指定的tags的task,其它的task不会被执行)

ansible-playbook -t shttpd httpd.yml

也可以指定多个tags执行:

ansible webservers -m yum -a 'name=httpd state=absent'    # 卸载
ansible webservers -m shell -a 'rpm -q httpd'
ansible-playbook -t ihttpd,shttpd httpd.yml
ansible webservers -m shell -a "ss -tnl|grep :80"
# 也可以多个动作使用相同的tags

查看tags列表:

ansible-playbook httpd.yml --list-tags

7.6 playbook中使用变量

变量名:仅由字母,数字和下划线组成,且只能以字母开头
变量来源:

  1. ansible setup facts远程主机的所有变量都可以直接调用
  2. 在/etc/ansible/hosts中定义
    普通变量:主机组中主机单独定义,优先级高于公共变量
    公共(组)变量:针对主机组中所有主机定义统一变量
ansible webservers -m setup      # ansible收集的远程主机信息
ansible webservers -m setup -a "filter=ansible_nodename"   # 过滤,只看nodename
  1. 通过命令行指定变量,优先级最高
ansible-playbook -e varname=value
  1. 在playbook中定义
  2. 在role中定义。变量优先级: 命令行 > yml > hosts
[root@node01 ansible]# cat app.yml
---
- hosts: appservers
  remote_user: root
  tasks:
    - name: install package
      yum: name={{ pkname }}
    - name: start service
      service: name={{ pkname }} state=started enabled=yes

yml文件中定义了变量,在命令行中对变量进行赋值

ansible-playbook -e 'pkname=vsftpd' app.yml
ansible appservers -m shell -a 'ss -tnl|grep :21'
ansible-playbook -e 'pkname1=httpd pkname2=memcached' app.yml   # 多个变量赋值
ansible appservers -m shell -a 'rpm -q httpd memcached'

在playbook中定义变量且赋值变量:

[root@node01 ansible]# cat app.yml
---
- hosts: appservers
  remote_user: root
  vars:
    - pkname1: httpd
    - pkname2: vsftpd
  tasks:
    - name: install package
      yum: name={{ pkname1 }}
    - name: install package
      yum: name={{ pkname2 }}

在hosts中定义变量:

[webservers]
172.17.2.240 http_port=81   # 只针对该主机有效
172.17.2.241 http_port=82
[webservers:vars]           # 公共变量,对整个webservers组都有效
nodename=www
domainname=ginvip.com
[root@node245 ansible]# cat hostname.yml
- hosts: webservers
  remote_user: root
  tasks:
    - name: set hostname
      hostname: name={{ nodename }}{{ http_port }}.{{ domainname }}

7.7 使用template

Jinja2语言,使用字面量

[root@node245 ansible]# cat templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }};
# nginx.conf.j2文件是复制nginx.conf文件而来
# ansible_processor_vcpus变量是通过执行ansible webservers -m setup|grep cpu获取
[root@node01 ansible]# cat test.yml
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: copy template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service
    - name: start service
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart service
      service: name=nginx state=restarted

因为模板中使用了worker_processes {{ ansible_processor_vcpus**2 }},当playbook执行后,进程数会是远程主机cpu核数的两倍

7.8 for循环

[root@node245 ansible]# cat templates/for1.conf.j2
{% for port in ports %}
server {
        listen {{ port }}
}
{% endfor %}
[root@node245 ansible]# cat for.yml
---
- hosts: webservers
  remote_user: root
  vars:
    ports:
      - 81
      - 82
      - 83
  tasks:
    - name: copy conf
      template: src=for1.conf.j2 dest=/tmp/for1.conf

7.9 when

条件测试:如果需要根据变量,facts或此前任务的执行结果来为某task执行与否的前提时要用条件测试,通过when语句实现

.................
    - name: copy template for centos7
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart service
      when: ansible_distribution_major_version=="7"		# Centos7执行该任务
    - name: copy template for centos6
      template: src=nginx.conf6.j2 dest=/etc/nginx/nginx.conf
      notify: restart service
      when: ansible_distribution_major_version=="6"		# Centos6执行该任务
...................

7.10 with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制

[root@node245 ansible]# cat testitem.yml
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: create some files
      file: name=/tmp/{{ item }} state=touch
      with_items:
        - file1
        - file2
        - file3
    - name: install some packages
      yum: name={{ item }}
      with_items:
        - htop
        - sl
        - hping3
[root@node01 ansible]# cat user.yml
---
- hosts: webservers
  remote_user: root
  tasks:
    - name: create some groups
      group: name={{ item }}
      with_items:
        - g1
        - g2
        - g3
    - name: create some users
      user: name={{ item.name }} group={{ item.group }}
      with_items:
        - { name: 'user1', group: 'g1' }
        - { name: 'user2', group: 'g2' }
        - { name: 'user3', group: 'g3' }

八:roles

Roles思想就是模块化,不同的文件放到不同的目录中
ansible roles目录编排:
Ansible自动化运维_第3张图片
roles目录结构(roles目录在哪都可以,官方推荐/etc/ansible/roles)

[root@node01 ansible]# tree
.
├── nginx_roles.yml
└── roles
    ├── mysql
    ├── nginx
    │   ├── tasks
    │   │   ├── group.yml
    │   │   ├── main.yml
    │   │   ├── restart.yml
    │   │   ├── start.yml
    │   │   ├── templ.yml
    │   │   ├── user.yml
    │   │   └── yum.yml
    │   └── templates
    │       └── nginx.conf.j2
    └── redis
# tasks目录中一个任务一个yml文件
# 执行顺序在main.yml中使用include按先后顺序将文件引入 

执行playbook:

ansible-playbook nginx_roles.yml

你可能感兴趣的:(Linux运维)