ansible基础知识

一、ansible简介

  • 1、ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

  • 2、ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。


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


    Ansible的架构
  • 3、ansible的安装
    ansible依赖于Python 2.6或更高的版本、paramiko、PyYAML及Jinja2。

(1)、编译安装

解决依赖关系

# 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

(2) 、rpm包安装

# yum install ansible

注意:不同版本的ansible的功能差异可能较大。

二、ansible中的模块使用和简单的格式执行

ansible -m MOD_nAME指明模块
-a MOD_ARGS 向模块传递参数
-f FORKS 一次可管理多少主机
-C 预运行,不真正运行
--list -host 列出主机
-u USERNAME 指明用户名
-c 指明连接方式,默认smart
这些命令使用ansible简单的格式执行

1、生成安全连接秘钥

ansible通过ssh实现配置管理、应用部署、任务执行等功能,因此,需要事先配置ansible端能基于密钥认证的方式联系各被管理节点。
ansible和目标主机命令执行要使用ssh,所以第一步就要生成安全连接秘钥。

[root@rs1 ~]# ssh-keygen -t rsa -P ""    #生成安全连接秘钥

[root@rs1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.6   #使用安全连接秘钥连接1号目标主机
 root@192.168.1.6's password: #输入目标主机密码

[root@rs1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.12 #使用安全连接秘钥连接2号目标主机
root@192.168.1.12's password:  #输入目标主机密码

2、添加本地解析

[root@rs1 ~]# vim /etc/hosts 添加本地解析

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.6 vs
192.168.1.12 rs2

3、定义目标主机组

/etc/ansible/hosts文件支持使用以下变量设置相关的远程主机信息:

ansible_ssh_host     #用于指定被管理的主机的真实IP
ansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是22
ansible_ssh_user     #ssh连接时默认使用的用户名
ansible_ssh_pass     #ssh连接时的密码
ansible_sudo_pass     #使用sudo连接用户时的密码
ansible_sudo_exec     #如果sudo命令不在默认路径,需要指定sudo命令路径
ansible_ssh_private_key_file     #秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项
ansible_shell_type     #目标系统的shell的类型,默认sh
ansible_connection     #SSH 连接的类型: local , ssh , paramiko,在 ansible 1.2 之前默认是 paramiko ,后来智能选择,优先使用基于 ControlPersist 的 ssh (支持的前提)
ansible_python_interpreter     #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
ansible_*_interpreter     #其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等

目标主机组:

[root@rs1 ~]# cd /etc/ansible
[root@rs1 ansible]# ls
ansible.cfg  hosts  roles
[root@rs1 ansible]# vim hosts#编辑文件
[websrvs]#添加web组
192.168.1.6
192.168.1.12

[dbsrvs] #定义db组
192.168.1.12

 [root@rs1 ansible]# ansible all  --list-hosts#列出目标主机
  hosts (2):
    192.168.1.12
    192.168.1.6
[root@rs1 ansible]# ansible all -m ping  -C# 对所有目标主机预运行ping测试
192.168.1.12 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.1.6 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@rs1 ansible]# ansible all -m ping # 对所有目标主机ping测试
192.168.1.12 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.1.6 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

4、模块文档

[root@rs1 ansible]# ansible-doc -l #列出目标主机模块文档
[root@rs1 ansible]# ansible-doc -s group 获取设置组命令文档
1、定义期望的目标状态
2、操作必须是幂等的,操作次数必须相等

5、group组模块使用

对目标主机创建组,并传递参数

[root@rs1 ansible]# ansible all -m group -a "gid=3000 name=mygrp state=present system=no" #对所有目标主机创建组,m是加载group模块,a是传递参数,state是创建还是删除
192.168.1.6 | SUCCESS => {
    "changed": true, 
    "gid": 3000, 
    "name": "mygrp", 
    "state": "present", 
    "system": false
}
192.168.1.12 | SUCCESS => {
    "changed": true, 
    "gid": 3000, 
    "name": "mygrp", 
    "state": "present", 
    "system": false
}

6、user用户模块使用

对目标主机创建用户,并传递参数

[root@rs1 ansible]# ansible all -m user -a "uid=5000 name=testuser state=present groups=mygrp shell=/bin/tcsh"对所有目标主机创建用户,m是加载user模块,a是传递参数,state是创建还是删除,groups是附加组,shell是默认shell

192.168.1.6 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 5000, 
    "groups": "mygrp", 
    "home": "/home/testuser", 
    "name": "testuser", 
    "shell": "/bin/tcsh", 
    "state": "present", 
    "system": false, 
    "uid": 5000
}
192.168.1.12 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 5000, 
    "groups": "mygrp", 
    "home": "/home/testuser", 
    "name": "testuser", 
    "shell": "/bin/tcsh", 
    "state": "present", 
    "system": false, 
    "uid": 5000
}

7、copy复制模块使用

对目标主机拷贝本地文件,并传递参数,指明src源文件位置和dest目标文件位置

[root@rs1 ansible]# ansible-doc -s copy#查询copy使用文档
[root@rs1 ansible]# ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
对所有目标主机拷贝本地文件,m是使用copy模块,a是传递参数,src源文件位置,dest目标文件位置,mode权限(加了'/'就是目录)
192.168.1.6 | SUCCESS => {
    "changed": true, 
    "checksum": "4367ba689c50b4ab956ce0704f048f4fb0cc1a28", 
    "dest": "/tmp/fstab.ansible", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "c6ac458a97ee2f7ed913fdc8b17e9394", 
    "mode": "0600", 
    "owner": "root", 
    "size": 465, 
    "src": "/root/.ansible/tmp/ansible-tmp-1534522522.24-76431722279920/source", 
    "state": "file", 
    "uid": 0
}
192.168.1.12 | SUCCESS => {
    "changed": true, 
    "checksum": "4367ba689c50b4ab956ce0704f048f4fb0cc1a28", 
    "dest": "/tmp/fstab.ansible", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "c6ac458a97ee2f7ed913fdc8b17e9394", 
    "mode": "0600", 
    "owner": "root", 
    "size": 465, 
    "src": "/root/.ansible/tmp/ansible-tmp-1534522522.23-209859323698602/source", 
    "state": "file", 
    "uid": 0
}

copy模块设置属主属组用法

[root@rs1 ansible]# ansible all -m copy -a "content='hi tere\n' dest=/tmp/hi.txt owner=testuser group=mygrp"#对所有目标主机拷贝本地文件,m是使用copy模块,a是传递参数,content创建文档到dest目标文件位置,设置属主属组
192.168.1.6 | SUCCESS => {
    "changed": true, 
    "checksum": "50dbdebeaa8c0f1c3cccfcae54ef71fc2c0e4fa8", 
    "gid": 3000, 
    "group": "mygrp", 
    "mode": "0644", 
    "owner": "testuser", 
    "path": "/tmp/hi.txt", 
    "size": 8, 
    "state": "file", 
    "uid": 5000
}
192.168.1.12 | SUCCESS => {
    "changed": true, 
    "checksum": "50dbdebeaa8c0f1c3cccfcae54ef71fc2c0e4fa8", 
    "gid": 3000, 
    "group": "mygrp", 
    "mode": "0644", 
    "owner": "testuser", 
    "path": "/tmp/hi.txt", 
    "size": 8, 
    "state": "file", 
    "uid": 5000
}

8、fetch复制模块

从远程单一主机复制到本地主机
使用文档:ansibile-doc -s fetch

9、command模块执行命令

对目标主机执行命令

[root@rs1 ansible]# ansible all -m command -a "ifconfig"#对所有目标主机,m使用模块,command命令模块,a传递参数 执行ifconfig命令
192.168.1.12 | SUCCESS | rc=0 >>
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
.............     
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
.............    

192.168.1.6 | SUCCESS | rc=0 >>
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
............... 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
...............     

注意:command缺点是无法解析管道命令

10、shell模块使用

shell模块解决了command模块的缺点,对传递参数用shell解析并执行

[root@rs1 ansible]# ansible all -m shell -a "echo 123 | passwd --stdin testuser"#对所有目标主机使用shell解析传递参数中的管道命令
192.168.1.6 | SUCCESS | rc=0 >>
更改用户 testuser 的密码 。
passwd:所有的身份验证令牌已经成功更新。

192.168.1.12 | SUCCESS | rc=0 >>
更改用户 testuser 的密码 。
passwd:所有的身份验证令牌已经成功更新。

11、file模块文件属性命令

对目标主机,传递参数,创建文件、目录和软连接

[root@rs1 ansible]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"#对所有目标主机使用file模块创建hello.dir目录
192.168.1.12 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/var/tmp/hello.dir", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
192.168.1.6 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/var/tmp/hello.dir", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}

[root@rs1 ansible]# ansible all -m file -a"src=/etc/fstab path=/var/tmp/fstab.link state=link"#对所有目标主机使用file模块创建fstab文件的符号连接
192.168.1.12 | SUCCESS => {
    "changed": true, 
    "dest": "/var/tmp/fstab.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 10, 
    "src": "/etc/fstab", 
    "state": "link", 
    "uid": 0
}
192.168.1.6 | SUCCESS => {
    "changed": true, 
    "dest": "/var/tmp/fstab.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 10, 
    "src": "/etc/fstab", 
    "state": "link", 
    "uid": 0
}

12、cron模块计划任务

对目标主机,传递参数,设置计划任务

[root@rs1 ansible]# ansible all -m crom -a "minute=*/3 job='/usr/sbin/update 192.168.1.1 &> /dev/null' name=none state=present"#对所有目标主机 ,m使用模块,crom计划任务,创建任务每三分钟同步时间

13、yum模块安装软件程序包

rpm软件的安装

[root@rs1 ansible]# ansible all -m yum -a "name=ngix state=instlled"#对所有主机安装ngix

14、service模块管理目标服务

对目标主机,传递参数,管理服务。

[root@rs1 ansible]# ansible all -m service -a"name=httpd state=started"#对所有主机启动httpd服务
[root@rs1 ansible]# ansible all -m service -a"name=httpd state=stoped"#对所有主机停止httpd服务

15、script模块脚本管理

[root@rs1 ansible]# vim /tmp/test.sh#编写一个测试脚本
对目标主机,传递参数,执行本地bash脚本

#!binbash
#
echo "ansible script" > /tmp/ansible.txt
[root@rs1 ansible]# ansible all -m script -a "/tmp/test.sh"#所有目标主机执行本地bash脚本

注意:ansible普通命令用法很难复用

三、playbook

  • playbook解决了ansible普通命令难以复用的缺点,使用yaml格式保存,所有首先要了解YAML。
  • playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。

1、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表达能力强,扩展性好

2、YAML语法

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

  • 服务安装示例(redis服务)
[root@rs1 ~]# mkdir playbooks#创建目录
[root@rs1 ~]# cd playbooks
[root@rs1 playbooks]# ls
[root@rs1 playbooks]# vim first.yaml#创建一个新的以.yaml 结尾的playbooks

- hosts: all #定义目标主机
  remote_user: root#使用用户
  tasks: #任务
  - name: install redis#将要执行的第一个任务
    yum: name=redis state=latest#执行任务的设置
  - name: name: start redis#将要执行的第二个任务
    service: name=redis state=started#执行任务的设置

[root@rs1 playbooks]# ansible-playbook --syntax-check first.yaml#语法检查

playbook: first.yaml
[root@rs1 playbooks]# ansible-playbook --list-hosts first.yaml#此playbooks涉及到那些主机

playbook: first.yaml

  play #1 (all): all    TAGS: []
    pattern: [u'all']
    hosts (2):
      192.168.1.12
      192.168.1.6
[root@rs1 playbooks]# ansible-playbook --list-hosts --list-tasks first.yaml#涉及到的主机上将要执行的任务(标签为空)

playbook: first.yaml

  play #1 (all): all    TAGS: []
    pattern: [u'all']
    hosts (2):
      192.168.1.12
      192.168.1.6
    tasks:
      install redis TAGS: []
      start redis   TAGS: []
      start redis   TAGS: []
[root@rs1 playbooks]# ansible-playbook -C first.yaml #预执行

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.6]
ok: [192.168.1.12]

TASK [install redis] ***********************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

TASK [start redis] *************************************************************
changed: [192.168.1.6]
changed: [192.168.1.12]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=3    changed=2    unreachable=0    failed=0   
192.168.1.6                : ok=3    changed=2    unreachable=0    failed=0   
[root@rs1 playbooks]# ansible-playbook  first.yaml #执行

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

TASK [install redis] ***********************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

TASK [start redis] *************************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=3    changed=2    unreachable=0    failed=0   
192.168.1.6                : ok=3    changed=2    unreachable=0    failed=0   
  • 配置文件传递示例(redis服务):
[root@rs1 playbooks]# cp 192.168.1.6/etc/redis.conf  ./
[root@rs1 playbooks]# ls
192.168.1.6  first.yaml  redis.conf
[root@rs1 playbooks]# ansible 192.168.1.6 -m fetch -a "src=/etc/redis.conf dest=./ " #复制目标主机里面的redis配置文件到本机
[root@rs1 playbooks]# cp 192.168.1.6/etc/redis.conf  ./#拷贝复制过来的配置文件到当前目录
[root@rs1 playbooks]# ls
192.168.1.6  first.yaml  redis.conf

[root@rs1 playbooks]# vim redis.conf#编辑
......
bind 0.0.0.0#监听所有端口
.....
requirepass foobared#启用密码认证功能,密码是foobared
.....
  • handlers:用特定条件触发使用
    用于当关注的资源发生变化时采取一定的操作。

    “notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

[root@rs1 playbooks]# cp first.yaml  second.yaml#备份一下
[root@rs1 playbooks]# vim second.yaml #编辑

- hosts: all
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis state=latest
  - name: copy config file  #任务2复制文件
    copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=r
edis#复制文件到目标主机目录下
    notify: restart redis#通知handlers触发
  - name: start redis
    service: name=redis state=started
  handlers:#定义触发任务
    - name: restart redis#触发任务一
      service: name=redis state=restarted#重新启动redis
[root@rs1 playbooks]# ansible-playbook --syntax-check second.yaml#语法检查

playbook: second.yaml
[root@rs1 playbooks]# ansible-playbook  second.yaml

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

TASK [install redis] ***********************************************************
ok: [192.168.1.6]
ok: [192.168.1.12]

TASK [copy config file] ********************************************************
changed: [192.168.1.6]
changed: [192.168.1.12]

TASK [start redis] *************************************************************
ok: [192.168.1.6]
ok: [192.168.1.12]

RUNNING HANDLER [restart redis] ************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=5    changed=2    unreachable=0    failed=0   
192.168.1.6                : ok=5    changed=2    unreachable=0    failed=0   
  • tags标签的使用
    只执行标签里面的任务
[root@rs1 playbooks]# vim second.yaml 

- hosts: all
  remote_user: root
  tasks:
  - name: install redis
    yum: name=redis state=latest
  - name: copy config file
    copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis
    notify: restart redis
    tags: configfile        #添加任务标签
  - name: start redis
    service: name=redis state=started
  handlers:
    - name: restart redis
      service: name=redis state=restarted
[root@rs1 playbooks]# ansible-playbook -t configfile  second.yaml #只执行标签里面的任务

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

TASK [copy config file] ********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=2    changed=0    unreachable=0    failed=0   
192.168.1.6                : ok=2    changed=0    unreachable=0    failed=0   

四、Ansible基础元素

1、 变量variables

  • 变量命名:变量名仅能由字母、数字和下划线组成,且只能以字母开头。
(1)facts可直接调用
  • facts是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主机所支持的所有facts
[root@rs1 playbooks]# ansible 192.168.1.6 -m setup# setup模块获取目标主机信息


[root@rs1 playbooks]# vim thir.yaml#编辑

- hosts: 192.168.1.6
  remote_user: root
  tasks:
  - name: copy file
    copy: content={{ansible_env}} dest=/tmp/ansible.env#指定变量保存到目标主机目录下
[root@rs1 playbooks]# ansible-playbook --syntax-check thir.yaml#语法检查
[root@rs1 playbooks]# ansible-playbook  thir.yaml

PLAY [192.168.1.6] *************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.6]

TASK [copy file] ***************************************************************
changed: [192.168.1.6]

PLAY RECAP *********************************************************************
192.168.1.6                : ok=2    changed=1    unreachable=0    failed=0   
(2)ansible-playbook命令的命令行自定义变量

在运行playbook的时候也可以传递一些变量供playbook使用

[root@rs1 playbooks]# vim forth.yaml

- hosts: all
  remote_user: root
  tesks:
  - name: install package {{pkgname}} #定义安装程序包任务
    yum: name={{pkgname}} state=latest#安装什么包,由自定义变量提供
[root@rs1 playbooks]# ansible-playbook --syntax-check forth.yaml 语法检查
[root@rs1 playbooks]# ansible-playbook -e pkgname=memcached forth.yaml#指定安装包安装

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

TASK [install package] *********************************************************
changed: [192.168.1.6]
changed: [192.168.1.12]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=2    changed=1    unreachable=0    failed=0   
192.168.1.6                : ok=2    changed=1    unreachable=0    failed=0   
(3)Inventory主机文件清单
  • ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。默认的inventory file为/etc/ansible/hosts。

  • 主机文件清单可以有多个,且也可以通过Dynamic Inventory来动态生成。

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

ntp.xxx.com
[webservers]
www1.xxx.com:2222
www2.xxx.com
[dbservers]
db1.xxx.com
db2.xxx.com
db3.xxx.com

如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机,

例如:[webservers]
www[01:50].xxx.com
[databases]
db-[a:f].xxx.com

[root@rs1 ansible]# vim hosts
........
 [websrvs]
www[1:7].hehe.com#定义主机清单
[root@rs1 ansible]# ansible websrvs --list-host
  hosts (7):
    www1.hehe.com
    www2.hehe.com
    www3.hehe.com
    www4.hehe.com
    www5.hehe.com
    www6.hehe.com
    www7.hehe.com


为目标主机创建用户
[root@rs1 playbooks]# vim fif.yaml #编辑文件

- hosts: all
  remote_user: root
  tasks:
  - name: add user
    user: name=test system=no state=present
  - name: set password
    shell: echo test | passwd --stdin test
[root@rs1 playbooks]# ansible-playbook --syntax-check fif.yaml#语法检查
[root@rs1 playbooks]# ansible-playbook --syntax-check fif.yaml

playbook: fif.yaml
[root@rs1 playbooks]# ansible-playbook  fif.yaml

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

TASK [add user] ****************************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

TASK [set password] ************************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=3    changed=2    unreachable=0    failed=0   
192.168.1.6                : ok=3    changed=2    unreachable=0    failed=0  
(4)主机变量

可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用。

[root@rs1 playbooks]# vim /etc/ansible/hosts 
[websrvs]
192.168.1.6 ansible_ssh_user=test ansible_ssh_pass=test
192.168.1.12 ansible_ssh_user=test ansible_ssh_pass=test

[root@rs1 playbooks]# ansible websrvs -m ping#对目标主机ping测试
192.168.1.12 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.1.6 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@rs1 playbooks]# ansible websrvs -m command -a  "whoami"#用户名返回测试
192.168.1.12 | SUCCESS | rc=0 >>
test

192.168.1.6 | SUCCESS | rc=0 >>
test
    注意: 一个组定义了指定用户 ,将会影响其他组指定用户会变的
(5)组变量

组变量是指赋予给指定组内所有主机上的在playboo中可用的变量。

自定义变量传递:
组变量定义方法一:
[websrvs]
192.168.1.6 http_port=8000
192.168.1.12 http_port=10080


组变量定义方法二:

[websrvs]
192.168.1.6 
192.168.1.12 
[websrvs:vars]
http_port=8080


[root@rs1 ~]# cd /root/playbooks/
[root@rs1 playbooks]# vim vars.yaml

- hosts: websrvs
  remote_user: root
  vars:                      
  - pbvar: playbook variable testing   #变量声明
  tasks:
  - name: command line variables
    copy: content={{ cmdvar }} dest=/tmp/cmd.var   #命令行变量引用,保存到指定文件
  - name: playbook variables
    copy: content={{ pbvar }} dest=/tmp/pb.var   #变量引用,保存到指定文件
  - name: host iventory variables
    copy: content={{ http_port }} dest=/tmp/hi.var  #主机列表定义引用,保存到指定文件
     [root@rs1 playbooks]# vim /etc/ansible/hosts 
[root@rs1 playbooks]# ansible-playbook -e cmdvar="command line variable testing" vars.yaml     #执行命令测试 
PLAY [websrvs] *****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.12]
ok: [192.168.1.6]

TASK [command line variables] **************************************************
changed: [192.168.1.6]
changed: [192.168.1.12]

TASK [playbook variables] ******************************************************
changed: [192.168.1.12]
changed: [192.168.1.6]

TASK [host iventory variables] *************************************************
changed: [192.168.1.6]
changed: [192.168.1.12]

PLAY RECAP *********************************************************************
192.168.1.12               : ok=4    changed=3    unreachable=0    failed=0   
192.168.1.6                : ok=4    changed=3    unreachable=0    failed=0   

(6)组嵌套

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

[apache]
httpd1.xxx.com
httpd2.xxx.com

[nginx]
ngx1.xxx.com
ngx2.xxx.com

[webservers:children]
apache
nginx

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

2、模板模块template

文本文档脚本,使用模板语言编写,支持Jinja2表达式语法

[root@rs1 playbooks]# cp redis.conf redis.conf.j2
[root@rs1 playbooks]# vim redis.conf.j2  #编辑文件
....
bind {{ ansible_ens33.ipv4.address }} #编辑模板段变量
.....                         
[root@rs1 playbooks]# vim template.yaml  #编辑playbook

- hosts: 192.168.1.6
  remote_user: root
  tasks:
  - name: install config file
    template: src=/root/playbooks/redis.conf.j2 dest=/tmp/redis.conf
[root@rs1 playbooks]# ansible-playbook template.yaml#执行
PLAY [192.168.1.6] *************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.1.6]

TASK [install config file] *****************************************************
changed: [192.168.1.6]

PLAY RECAP *********************************************************************
192.168.1.6                : ok=2    changed=1    unreachable=0    failed=0   

客户端:

[root@vs ~]# vim /tmp/redis.conf
.......
bind 192.168.1.6    #已把客户主机ip写入redis里面了
........  

示例二:
不同主机,得到不同的配置

vim listen.conf
listen {{ http_port }}

vim httpd.yaml
- hosts:websrvs
 remote_user: root
 tasks:
   - name: install httpd
    yum: name=httpd state=latest
   - name: install config file
    template: src=/root/playbooks/mylisten.conf dest=/etc/httpd/conf.d/mylinsten.conf
- name: start httpd
service: name=httpd state=started

ansible-playbook --syntax-check httpd.yaml
ansible-playbook httpd.yaml

3、when语句条件测试语句:

  • 如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试。

  • 在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法。

when:在task中使用,jinja2的语法格式
.- name: install conf file
template:src=files
when:什么时候执行任务

判断当前系统是debian系统,就按照Apache2

示例:

vim os.yaml
      - hosts: websrvs
       remote_user: root
       tasks:
       - name: install httpd
        yum: name=httpd state=latest  
        when:ansible_os_family ==" RedHat"#判断是否是红帽系统
        - name: install apche2
        apt: name=apache2 state=latest
        when: ansible_os_family == "Debian"#判断是否是debian系统
ansible-playbook -c os.yaml

when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下形式:

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中定义的变量

4、迭代

  • 当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。
示例:安装多个程序包
        vim  iter.yaml
        - hosts: websrvs
         remote_user: root
         tasks:
         - name:  instsll {{ item }} package
          yum: name= {{ item }} state=latest#安装with_items里面的程序包
          with_items:
          - tomcat
          - tomcat-webapps
          - mariadb-server
    ansible-playbook  iter.yaml

5、角色:roles

  • ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

  • 自包含的目录,以特定的层级目录结构化组织
    mkdir -pv /etc/ansible/roles/nginx/{files,templates,tasks,vars,handlers,meta,default}

示例:利用roles安装nginx,并配置启动
cd /etc/ansible
vim roles/nginx/templates/vhost1.conf.j2 #编辑模板文件
   server{
           lisen 8080;
           server_name {{ anible_fqdn }}; 获取主机名
           location / { 
                    root "/ngxdata/vhost1";
             }
           }
vim roles/nginx/files/index.html#编辑测试页
   <h1>vhost</h1>

vim roles/nginx/handers/main.yml #编辑触发文件
   - name: restart nginx
    service: name=nginx  state=restarted

vim roles/nginx/vars/main.yml#编辑变量文件
   ngxroot: /ngxdata/vhost1   #这里定义必须是字典模式,不加'-'

vim /etc/ansible/roles/nginx/tasks/main.yml
    - name:  install nginx
     yum: name=nginx state=latest
     when: ansible_os_family == "RedHat"#检查是否是红帽系统
    - name: install conf
     temlate: src=vhost1.conf.j2 dest=/etc/nginx/conf.d/vhost1.conf#传递模板文件
     tags: conf  标签
     notify: restart nginx
    -name: install site home directory
     file: path={{ ngxroot }} state=directory
    -name: install index page
     copy: src=index.html dist={{ ngxroot }}/#拷贝本地index测试页到目标主机的nginx根目录
    -name: start nginx
     service:name=nginx state=started#启动nginx

cd   
vim nginx.yml
   - hosts: websrvs
     remote_user: root
    roles:
     - nginx   #调用角色

ansible-playbook -syntax-check nginx.yml #语法检查
ansible-playbook nginx.yml #执行

四、配置文件设置常用设置

配置文件设置

vim  ansible.cfg

[defaults]
forks=5  一次管控多少主机
sudo_user=root  切换到那个管理员  
ask_pass=true   切换时候是否需要密码
remote_port =22 远程端口

roles_path  角色存放位置
module_name  不指明时候 调用默认模块

客户端主机主动到ansible服务器获取配置用ansible-vcs第三方软件来实现,实际应用中较少使用。

参考链接:https://www.jianshu.com/p/3d50899842e2

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 1)安装2)常用模块3)inventory4)playbook(role\tag\template)5) yaml...
    秦记阅读 4,117评论 2 5
  • 一、简介 在Linux自动化运维中,常见的自动化运维工具可分为需要安装终端的puppet、func和不需要安装终端...
    小尛酒窝阅读 2,651评论 0 6
  • Ansible主配置文件:/etc/ansible/ansible.cfgInventory配置文件:/etc/a...
    剑胆琴心python阅读 1,081评论 0 2
  • ansible-playbook playbook简介 playbook是ansible用于配置,部署,和管理被控...
    bdslinux阅读 10,833评论 1 12
  • 简介 架构 原理 组成 ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置...
    毛利卷卷发阅读 1,040评论 0 2