Ansible----deepin

Ansible 工具的特点概述

ansible 优点

只需要SSH 和Python 即可使用
无客户端
ansible 功能强大,模块丰富
上手容易,门槛低
基亍Python 开发,做二次开发更容易
使用公司比较多,社区活跃

ansible 特性

模块化设计,调用特定的模块完成特定任务
基于Python 语言实现
Paramiko、PyYAML (半结构化语言)
Jinja2
其模块支持JSON 等标准输出格式,可以采用任何编程语言重写
部署简单
主从模式工作
支持自定义模块
支持playbook
易亍使用
支持多层部署
支持异构IT 环境

Ansible 服务的安装和部署

ansible 安装
软件依赖关系
(1)对管理主机

要求Python 2.6版本以上
ansible 使用以下模块,都需要安装
paramiko、PyYAML、Jinja2、httplib2、six

(2)对于被托管主机

<1>ansible 默认通过SSH 协议管理机器
<2>被管理主机要开启ssh 服务,允许ansible 主机登彔
<3>在托管节点上也需要安装Python2.5以上的版本
Ansible 的安装
pip install -y paramiko PyYAML Jinja2 httplib2 six #安装ansible 的依赖
apt install -y ansible #安装ansible

ansible 配置文件

配置文件目录: /etc/ansible/
执行文件目录: /usr/bin/
ib 依赖库: /usr/lib/python2.7/site-packages/ansible/
help 文件: /usr/lib/python2.7/site-packages/ansible

ansible 配置文件查找顺序

检查环境变量ANSIBLE_CONFIG 指向的路径文件(export
ANSIBLE_CONFIG=/etc/ansible.cfg);
./ansible.cfg,检查当前目录下的ansible.cfg 配置文件;
~/ansible.cfg 检查当前用户家目录下
/etc/ansible.cfg 检查etc 目录的配置文件。

ansible 配置文件参数详解/etc/ansible/ansible.cfg

ansible 有许多参数,下面我们列出一些常见的参数:
inventory = /etc/ansible/hosts #这个参数表示资源清单inventory 文件的位置
library = /usr/share/ansible #指向存放Ansible 模块的目录,支持多个目录方式,
只要用冒号(:)隔开就可以
forks = 5 #并发连接数,默认为5
sudo_user = root #设置默认执行命令的用户
remote_port = 22 #指定连接被管节点的管理端口,默认为22端
口,建议修改,能够更加安全
host_key_checking = False #设置是否检查SSH 主机的密钥,值为True/False。
关闭后第一次连接不会提示配置实例
timeout = 60 #设置SSH 连接的超时时间,单位为秒
log_path = /var/log/ansible.log #指定一个存储ansible 日志的文件(默认不记录
日志)

定义Inventory(主机列表)

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

Inventory 文件格式:

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

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

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

[webservers]
www[01:50].example.com
[databases]
db-[a:f].example.com

inventory 其他的参数
ansible 基于ssh 连接inventory 中指定的远程主机时,还可以通过参数指定其交互方式;这些参数如下所示:

ansible_ssh_host # 远程主机
ansible_ssh_port # 指定远程主机ssh 端口
ansible_ssh_user # ssh 连接远程主机的用户,默认root
ansible_ssh_pass # 连接远程主机使用的密码,在文件中明文,建议使用--ask-pass 或者使用SSH keys
ansible_sudo_pass # sudo 密码, 建议使用--ask-sudo-pass
ansible_connection # 指定连接类型: local, ssh, paramiko
ansible_ssh_private_key_file # ssh 连接使用的私钥
ansible_shell_type # 指定连接对端的shell 类型, 默认sh,支持csh,fish
ansible_python_interpreter # 指定对端使用的python 编译器的路径

Ansible 基础应用

SSH 服务的免密钥登录
Ansible 是基于ssh 连接的,为方便管理,一般我们会首先配置管理机登陆被管理机的免密认证,以及其它一些必要的配置。
示例:
1、准备虚拟机
4台虚拟机:
(ansible 192.168.200.10)
(node1 192.168.200.11)
(node2 192.168.200.12)
(node3 192.168.200.13)
2、配置免密登陆和hosts 解析
ssh-keygen 一直回车#生成密钥
ssh-copy-id node1 #拷贝私钥
所有机器都必须是免密登陆
4台主机上面配置/etc/hosts,以ansible 主机为例
vim /etc/hosts

192.168.200.10 ansible
192.168.200.11 node1
192.168.200.12 node2
192.168.200.13 node3

Copy 到每台主机:

for i in {10..13}; do scp /etc/hosts 192.168.200.$i:/etc/hosts; done

3、安装ansible

apt install -y ansible

4、配置主机清单

vim /etc/ansible/hosts
[web]
node1
node2
[db]
node3

5、结果测试

ansible all -m ping
node2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node3 | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible web -m ping
node2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
node1 | SUCCESS => {
"changed": false,
"ping": "pong"
}

Ansible 的常用命令和常用模块参数

ad-hoc 单行命令执行模式
批量执行单条任务,相当于在某个范围服务器组中的每一台上执行一个任务命令,如安装软件、copy 文件等
获得模块的帮助文档

ansible-doc -l 列出所有可用的模块, 版本2.7.7, 2078 个模块
ansible -s <module-name> 可以查看指定module 的用法
参看官方帮助文档

参看官方帮助文档
示例:

ansible-doc -s apt
ansible-doc -l| wc -l

语法格式

ansible <host-pattern> [options]

常用格式:

ansible 主机模式-m 模块[-a '参数'] [-i 主机清单文件]
常用选项:
-b,--become:特权方式运行命令。
-s, 以sudo 来运行命令
-m:要使用的模块名称。
-a,--args:制定模块所需的参数。
-u:制定连接的用户名。
-h,--help 显示帮助内容。
-v,--verbose 以详细信息模式运行命令,可以用来调试错误。

示例:

ansible all -m apt -a “name=apache2 state=present”-b

主机模式
ansible 支持主机列表的正则匹配

全量: all/*
逻辑或: :
逻辑非: !
逻辑与: &
切片:[]
正则匹配:以~开头

示例:

ansible all -m ping #所有默认inventory 文件中的机器
ansible "*" -m ping #同上
ansible 121.28.13.* -m ping #所有122.28.13.X 机器
ansible web1:web2 -m ping #所有属于组web1 或属于web2 的机器
ansible web1:!web2 -m ping #属于组web1,但不属于web2 的机器
ansible web1&web2 -m ping #属于组web1 又属于web2 的机器
ansible webserver[0] -m ping #属于组webserver 的第1 台机器
ansible webserver[0:5] -m ping #属于组webserver 的第1 到4 台机器
ansible "~(beta|web)\.example\.(com|org)" -m ping

示例:

多个组的并集
ansible web,db -m ping
或者
ansible 'web:db' -m ping
多个组的交集
ansible 'web:&db' -m ping
多个组的差集
ansible 'web:!db' -m ping
注意:其中括起组名的必须是单引号''

Ansible 常用的模块
文件模块

copy:把文件从本机拷贝到远程
file:设置文件的权限等属性
lineinfile:确保文件中存在或不存在某些行
syncchronize:能过rsync 同步内容

软件包模块

package:通过自动检测,使用操作系统原生的包管理器管理软件
apt:通过apt 进行软件包管理
mount:文件系统挂载
dnf:通过dnf 进行软件包管理
gem:管理Ruby gems
pip:从PyPI 进行python 包管理

系统模块

firewall:通过firewall 管理服务和端口
reboot:重启主机
service:管理服务
user:添加、删除、管理用户

网络工具模块

get_url:通过htp/htts/ftp 下载文件
nmcli:管理网络
uri:与Web 服务交互

Ansible 的模块实例和模块的综合应用

1、ping 模块

ansible all -m ping #查看ping 客户端组情况

2、command 命令模块

ansible all -m command -a "uptime" #查看客户端负载信息
ansible all -m command -a "useradd deepintest" #在客户端添加用户
ansible all -m command -a "touch /deepintest" #在客户端建立文件
ansible all -m command -a "chdir=/tmp pwd" #先改变目录,再执行pwd

3、shell 模块

让远程主机在shell 进程下执行命令,从而支持shell 的特性,如管道等

ansible all -m shell -a "echo "deepintest:deepintest" | chpasswd"

chdir:在运行命令之前,切换到此目录。

ansible web -m shell -a "chdir=/tmp pwd"

executable:更改用于执行命令的shell(bash,sh)。应该是可执行文件的绝对路径。

4、script 模块
将deepin1 上的脚本在deepin2、deepin3 和deepin4 上运行

vim /tmp/deepinscript.sh
#!/bin/bash
touch /tmp/deepinscript
useradd deepinscript
echo "deepinscript:deepinscript" | chpasswd

在所有主机上批量执行deepinscript 脚本

ansible all -m script -a "/tmp/deepinscript.sh"

5、copy 模块

ansible all -m copy -a "src=/etc/fstab dest=/tmp/ owner=deepintest group=root mode=0600"
ansible all -m copy -a "src=/var/log/apt/ dest=/tmp/ owner=deepintest group=root mode=0750"

#src 主控端文件位置,dest 被控端目标位置,owner 文件复制过去后的所有者,group 文件复制过去后的所属组,mode 文件的权限设定
6、user 模块

ansible all -m user -a "name=deepinuser state=present groups=deepintest uid=2000 createhome=yes home=/tmp/deepinuser password=deepinuser shell=/bin/bash comment='The user for deepin' append=yes"

ansible all -m user -a "name=deepinuser state=absent remove=yes"

name:用户名
password:为用户设置登陆密码,此密码是明文密码加密后的密码
update_password:always/on_create
always:只有当密码不相同时才会更新密码(默认)
on_create:只为新用户设置密码
shell:用户的shell 设定
groups:用户组设定
home:指定用户的家目录
state:present/absent
append:yes/no
yes:增量添加group
no:全量变更group,只设置groups 指定的group 组(默认)
remove:配合state=absent 使用,删除用户的家目录->remove=yes
expires:设置用户的过期时间,值是一个时间戳

7、file 模块

ansible all -m file -a "src=/etc/fstab dest=/tmp/deepinfstab state=link"
ansible all -m file -a "path=/tmp/deepinfile state=touch owner=deepintest group=root mode=0600"

force:需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况
下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个
选项:yes|no
group:定义文件/目录的属组
mode:定义文件/目录的权限
owner:定义文件/目录的属主
path:必选项,定义文件/目录的路径
recurse:递归设置文件的属性,只对目录有效
src:被链接的源文件路径,只应用于state=link 的情况
dest:被链接到的路径,只应用于state=link 的情况
state:

	directory:如果目录不存在,就创建目录
	file:即使文件不存在,也不会被创建
	link:创建软链接
	hard:创建硬链接
	touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
	absent:删除目录、文件或者取消链接文件

8、mount 模块

ansible all -m mount -a "src=/dev/sr0 path=/mnt/cdrom fstype=iso9660 opts=ro state=mounted"
ansible all -m mount -a "src=/dev/sr0 path=/mnt/cdrom fstype=iso9660 opts=ro state=absent"

fstype:必选项,挂载文件的类型
path:必选项,挂载点
opts:传递给mount 命令的参数
src:必选项,要挂载的文件
state:

		present 添加到fstab 中,不挂载
		absent 删除fstab,并卸载资源
		mounted 添加到fstab 中,并自动挂载
		umounted 不删除fstab 信息,只卸载资源

9、service 模块

ansible all -m service -a "name=sshd state=started enabled=yes"

arguments:给命令行提供一些选项
enabled:是否开机启动yes|no, 要求状态(state)和启用(enabled)中至少有一个。
name:必选项,服务名称
runlevel:运行级别
sleep:如果执行了restarted,在则stop 和start 之间沉睡几秒钟
state :对当前服务执行启动,停止、重启、重新加载等操作
(started,stopped,restarted,reloaded)
10、setup 模块

ansible all -m setup #查看所有主机信息
ansible all -m setup -a "filter=ansible_hostname" #查看主机名
ansible all -m setup -a "filter=ansible_kernel" #查看内核信息
ansible all -m setup -a "filter=ansible_memory_mb" #查看内存信息
ansible all -m setup -a "filter=ansible_default_ipv4" #查看网卡ipv4 信息
ansible all -m setup -a "filter=*user*" #查看user 相关信息

11、debug 模块

ansible all -m debug -a "msg=hahahahahaha"

msg:调试输出的消息
var:将某个任务执行的输出作为变量传递给debug 模块,debug 会直接将其打印输出
verbosity:debug 的级别(默认是0 级,全部显示)
12、cron 计划任务模块

ansible all -m cron -a "name='deepincron' minute='30' hour='12' job='touch /tmp/deepincron' user=root"
ansible all -m cron -a 'minute="*/1" job="/usr/bin/date >> /date.txt" name="date job"'

minute= /hour= /day= /month= /weekday= 某个值不写,默认就是*
name:必选项,任务描述信息
job:执行的任务,要加引号
state:present(创建)/absent(删除)
13、get_url 模块

ansible all -m get_url -a 'url=http://192.168.200.10/favicon.ico dest=/tmp' #配置好url

sha256sum:下载完成后进行sha256 check;
timeout:下载超时时间,默认10s
url:下载的URL
url_password、url_username:主要用于需要用户名密码进行验证的情况
dest:将文件下载到哪里的绝对路径。如果dest 是目录,则使用服务器提供的文件名,
或者如果没有提供,将使用远程服务器上的URL 的基本名称。
headers:以格式“key:value,key:value”为请求添加自定义HTTP 标头。
14、synchronize 模块
用于在主机间同步数据
delete=yes 使两边的内容一样(即以推送方为主)
compress=yes 开启压缩,默认为开启
–exclude=.Git 忽略同步.git 结尾的文件
mode=pull 更改推送模式为拉取模式
示例:
在deepin1 上

mkdir /deepin
touch /deepin/file{1..99}
ansible all -m synchronize -a 'src=/deepin dest=/tmp/ compress=yes'

在deepin2 上

ll /tmp/deepin

在deepin1 上

mkdir /deepintest
ansible node1 -m synchronize -a ' mode=pull src=/tmp/deepin dest=/deepintest'
ll /deepintest/deepin

Ansible 高级应用

playbook 内容介绍和语法格式
playbook 模式(剧本模式)

Playbook 是Ansible 提供的最强大的任务执行方法。与ad-hoc 命令不同,Playbooks 配置在文件中,可以重用和共享给其他人。
playbooks 是以YAML 标记语言来定义的。每个playbook 由一个或多个play 组成。play
的目标是将一组主机映射到任务中去。每个play 包含一个或多个任务(task),这些任务每次执一次。
从根本上来讲,所谓task 无非是调用ansible 的一个module。将多个play 组织在一个
playbook 中,即可以让它们联同起来按事先编排的机制同唱一台大戏。
playbooks 的组成部分
Target section: 定义要运行playbook 的远程主机组
hosts: hosts 用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔主机组
user: 指定远程主机上的执行任务的用户,还可以指定sudo 用户等
Variable section: 定义playbook 运行时使用的变量
Task section: 定义要在远程主机上运行的任务列表
name: 每个任务都有name,建议描述任务执行步骤,未通过name 会用执行结果作为name
'module:options': 调用的module 和传入的参数args
Handler section: 定义task 完成后需要调用的任务
notify: 在Task Section 在每个play 的最后触发,调用在hendler 中定义的操作
handler: 也是task 的列表

示例:

---
-- hosts: master
  user: root
  vars:
	- motd_warning: 'WARNING: Use by master ONLY'
  tasks:
	- name: setup a MOTD
      copy: dest=/etc/motd content="{{ motd_warning }}"
      notify: say something
  handlers:
	- name: say something
	  command: echo "copy OK"

yaml 语法格式

同级别数据元素必须有相同的缩进
子元素必须比父元素缩进更多
推荐缩进两个空格
每个文件首行是“---”,最后一行是“...”
playbook 是play 的列表,列表项表示为“-”
paly 本身是key:val 对的字典

帮助查看

ansible-doc apt

执行playbook

ansible-playbook --syntax-check **.yml //检测语法格式
ansible-playbook **.yml //执行playbook

playbook 变量内容和变量定义

Ansible 变量简介
Ansible 支持利用变量来存储值,并在Ansible 项目的所有文件中重复使用这些值。这可化项目的创建和维护,并减少错误的数量。
通过变量,可以轻松地在Ansible 项目中管理给定环境的动态值。例如:
要创建的用户
要安装的软件包
要重新启动的服务
要删除的文件
要从互联网检索的存档
命名变量
变量的名称必须以字母开头,并且只能包含字母、数字和下划线。
示例:web server:错误的变量名web_server:正确的变量名
定义变量
可以在Ansible 项目中的多个位置定义变量。这些变量大致可简化为三个范围级别:
全局范围:从命令行或Ansible 配置设置的变量
play 范围:在play 和相关结构中设置的变量
主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
优先级:
命令行变量>>playbook 变量>>主机清单变量
ansible 变量优先级(由高到低)

1. ansible-playbook 命令中的变量,ansible-playbook -e var=value
2. task 变量
3. block 变量
4. role 中定义的变量和include 变量
5. set_fact
6. registered 变量
7. vars_files
8. var_prompt
9. play 变量
10. host facts
11. playbook 中设置的host_vars
12. playbook 中设置的group_vars
13. inventory 中设置的host_vars
14. inventory 中设置的group_vars
15. inventory 变量
16. role 中defaults/main.yml 中定义的变量

playbook 中的变量
变量在Ansible Playbook 中发挥着重要作用,因为它们可以简化playbook 中变量数据的管理。
在playbook 中定义变量
Playbook 变量可以通过多种方式定义。一种常见的方式是将变量放在playbook 开头的vars块中:

---
- hosts: 192.168.86.132
  vars:
    package_name: httpd
  tasks:
    - name: install httpd
      yum:
        name: '{{ package_name }}' #变量一定要写用引号
        state: present

也可以在外部文件中定义playbook 变量。此时不使用playbook 中的vars 块,可以改为使用
vars_files 指令,后面跟上相对于playbook 位置的外部变量文件名称列表:

[root@ansible playbook]# mkdir vars && cd vars && echo "package_name: httpd" > httpd.yml
[root@ansible playbook]# vim test.yml
---
- hosts: 192.168.86.132
    vars_files:
      - vars/httpd.yml
    tasks:
      - name: install httpd
          yum:
          name: '{{ package_name }}'
          state: present

注:
声明了变量后,可以在任务中使用这些变量。若要引用变量,可以将变量名放在双大括号内。在任务执行时,Ansible 会将变量替换为其值。需要注意的是:当变量用作开始一个值的第一元素时,必须使用引号。这可以防止Ansible 将变量引用视为YAML 字典的开头。

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

例如:
[webservers]
www1.com http_port=80 maxRequestsPerChild=808
www2.com http_port=8080 maxRequestsPerChild=909

组变量: 主机组变量针对组内所有的主机都生效。

示例:定义了2 个主机组变量ntp_server 和nfs_server
[webservers]
www1.com
www2.com
[webservers:vars]
ntp_server=ntp.com
nfs_server=nfs.com

测试:
vim variable.yaml

---
- hosts: all
    gather_facts: False
    tasks:
	  - name: diplay Host Variable from hostfile
	  debug: msg="The {{ inventory_hostname }} Value is {{ key }}"

执行:

ansible-playbook variable.yaml

注意:如果主机同时定义了主机变量和主机组变量,名字相同时,主机变量生效,主机组变量不生效;名字不同时,都可以调用。

从命令行覆盖变量
清单变量可被playbook 中设置的变量覆盖,这两种变量又可通过在命令行中传递参数到ansible 或ansible-playbook 命令来覆盖。在命令行上设置的变量称为额外变量,使用**-e**选择来指定额外变量

[root@ansible httpd]# ansible 192.168.86.132 -i inventory -e "ansible_passwrod=123456" -m ping

//也可以把变量写在一个文件中用-e 选项来指定

[root@ansible httpd]# vim xx

ansible_password: 123456

[root@ansible httpd]# ansible 192.168.86.132 -i inventory -e @xx -m ping

示例:使用已注册变量捕获命令输出

可以使用register 语句捕获命令输出。输出保存在一个临时变量中,然后在playbook 中可用于调试用途或者达成其他目的

---
- name:
    hosts: 192.168.86.132
    tasks:
      - name:
          user:
            name: cvg
            state: present
        register: useradd_result
      - debug: var=useradd_result //debug 模块用于将install_result 注册变量的值转储到终端。

[root@ansible ~]# ansible-playbook -C test.yml

管理机密和管理事实

管理机密
Ansible Vault
Ansible 可能需要访问密码或API 密钥等敏感数据,以便能配置受管主机,但是这些敏感数据是任何有权限访问Ansible 文件的用户都能查看,这样是不安全。
Ansible 提供的Ansible Vault 可以加密和解密任何由Ansible 使用的结构化数据文件。

创建加密文件
使用ansible-vault create filename 命令创建加密文件,然后输入的vault 密码

[root@ansible group_vars]# ansible-vault create webserve
New Vault password:
Confirm New Vault password:

还可以用vault 密码文件来存储vault 密码,而不是通过标准输入途径输入vault 密码。
这样做需要使用文件权限和其他方式来严密保护该文件。

[root@ansible group_vars]# vim vault_password
123456
[root@ansible group_vars]# ansible-vault create --vault-password-file=vault_password webserve

查看加密的文件
使用ansible-vault view filename 命令查看Ansible Vault 加密的文件

[root@ansible group_vars]# ansible-vault view webserve
Vault password:
ansible_password: 123456

编辑现有的加密文件
使用ansible-vault edit filename 命令。此命令将文件解密为一个临时文件,并允许编辑。保存时,它将复制其内容并删除临时文件。

[root@ansible group_vars]# ansible-vault edit webserve
Vault password:

注意:不要用vi/vim 直接编辑加密文件,这样会导致加密文件无法打开
加密现有的文件

使用ansible-vault encrypt filename 命令。此命令可取多个想要加密文件的名称作为参数。
//创建加密文件

[root@ansible group_vars]# vim webserve
ansible_password: 123456
[root@ansible group_vars]# ansible-vault encrypt webserve
New Vault password:
Confirm New Vault password:
Encryption successful

解密现有的文件
使用ansible-vault decrypt filename 命令永久解密。在解密单个文件时,可使用**_output**
选项以其他名称保存解密的文件。

[root@ansible group_vars]# ansible-vault decrypt webserve
Vault password:
Decryption successful

[root@ansible group_vars]# cat webserve
ansible_password: redhat

更改加密的密码
使用ansible-vault rekey filename 命令更改加密文件的密码。此命令可一次性更新多个数据文件的密钥。它将提示提供原始密码和新密码。

[root@ansible group_vars]# ansible-vault rekey webserve
Vault password: //当前密码
New Vault password: //输入要更改的新密码
Confirm New Vault password: //再次输入要更改的新密码
Rekey successful

在使用vault 密码文件时,请使用–new-vault-password-file 选项

ansible-vault rekey --new-vault-password-file=NEW_VAULT_PASSWORD_FILE webserve

playbook 和ansible vault
要运行可访问通过Ansible Vault 加密的文件的playbook,需要向ansible-playbook 命令提供加密密码。如果不提供密码,playbook 将返回错误

[root@ansible httpd]# ansible all -i inventory -m ping
ERROR! Attempting to decrypt but no vault secrets found

要为playbook 提供vault 密码,可使用–vault-id @prompt 选项。

[root@ansible httpd]# ansible 192.168.86.132 -i inventory --vault-id @prompt -m ping
Vault password (default):
192.168.86.132 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}

也可使用–vault-password-file 选项指定以纯文本存储加密密码的文件。密码应当在该文件中存储为一行字符串。由于该文件包含敏感的纯文本密码,因此务必要通过文件权限和其他安全措施对其加以保护。

ansible all --vault-password-file=vault-pw-file webserve

也可以使用ANSIBLE_VAULT_PASSWORD_FILE 环境变量,指定密码文件的默认位置。
从Ansible2.4 开始,可以通过ansible-playbook 使用多个Ansible Vault 密码。要使用多
个密码,需要将多个**–vault-id 或–vault-password-file 选项传递给ansible-playbook**命令。

ansible all --vault-id one@prompt --vault-id two@prompt webserve

//这种用法一般不会使用
注意:@prompt 前面的vaultIDone 和two 可以是任何字符,甚至可以完全省略它们。不过,如果在使用ansible-vault 命令加密文件时使用–vault-id id 选项,则在运行ansible-playbook时,将最先尝试匹配ID 的密码。如果不匹配,将会尝试用户提供的其他密码。没有ID 的vaultID@prompt 实际上是default@prompt 的简写,这意味着提示输入vaultIDdefault 的密码。变量文件管理的推荐做法

设置Ansible 项目,简化管理,使敏感变量和其他变量保存在相互独立的文件中。然后,包含敏感变量的文件可通过ansible-vault 命令进行保护。

管理组变量和主机变量的首选方式是在playbook 级别上创建目录。group_vars 目录通常包含名称与它们所应用的主机组匹配的变量文件。host_vars 目录通常包含名称与它们所应用的受管主机名称匹配的变量文件。

除了使用group_vars 和host_vars 中的文件外,也可对每一主机组或受管主机使用目录。这些目录可包含多个变量文件,它们都由该主机组或受管主机使用

[root@ansible httpd]# tree .

.
├──files
├──group_vars
│└──webserve
│├──vars //不需要加密的变量
│└──vault //需要加密的变量,用ansible-vault 进行加密
├──host_vars
├──inventory
└──playbook.yml

管理事实

描述Ansible 事实
setup 模块用来收集事实,每个play 在执行第一个任务之前会先自动运行setup 模块来收集事实。

Ansible 事实是Ansible 在受管主机上自动检测到的变量。事实中包含有与主机相关的信息,可以像play 中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用。

收集的事实可能包括:

主机名称
内核版本
网络接口
IP 地址
操作系统版本
各种环境变量
CPU 数量
提供的或可用的内存
可用磁盘空间

借助事实,可以方便地检索受管主机的状态,并根据该状态确定要执行的操作。
可以根据含有受管主机当前内核版本的事实运行条件任务,以此来重启服务器
可以根据通过事实报告的可用内存来自定义MySQL 配置文件
可以根据事实的值设置配置文件中使用的IPv4 地址

查看为受管主机收集的事实的一种方式是,运行一个收集事实并使用debug 模块显示
ansible_facts 变量值的简短playbook。

---
- name: fact
    hosts: 192.168.86.132
    tasks:
      - name: fact
          debug:
            var: ansible_facts

//Playbook 以JSON(字典)格式显示ansible_facts 变量的内容。

[root@ansible ~]# ansible-playbook play.yml

Ansible 事实的变量名
事实变量

短主机名ansible_facts[‘hostname’]
完全限定域名ansible_facts[‘fqdn’]
IPv4 地址ansible_facts[ ‘default_ipv4’] [‘address’]
/dev/vda1 磁盘分区的大小ansible_facts[‘devices’] [‘vda’] [‘partitions’] [‘vda1’]
‘size’]
DNS 服务器列表ansible_facts[‘dns’] [‘nameservers’]
当前运行的内核版本ansible_facts[‘kernel’]

示例:
取得主机名

---
- name: fact
   hosts: 192.168.86.132
   tasks:
     - name: fact
       debug:
           var: ansible_facts['hostname']
[root@ansible ~]# ansible-playbook play.yml

//取出sda 下的sda1 的分区大小

---
- name: fact
  hosts: 192.168.86.132
  tasks:
    - name: fact
      debug:
         var: ansible_facts['devices']['sda']['partitions']['sda1']['size']
[root@ansible ~]# ansible-playbook play.yml

如果变量的值为散列/字典类型,则可使用下面这种语法来获取其值
ansible_facts[‘dns’] [‘nameservers’]也可以写为ansible_facts.dns.nameservers,不推荐使用这种方法
//取得DNS server 变量

---
- name: fact
  hosts: 192.168.86.132
  tasks:
    - name: fact
      debug:
        var: ansible_facts.dns.nameservers
[root@ansible ~]# ansible-playbook play.yml

在playbook 中使用事实时,Ansible 将事实的变量名动态替换为对应的值
//取得机器名和对应的ip

---
- hosts: all
  tasks:
    - name: Prints various Ansible facts
      debug:
        msg: >
           The machine and ipv4 address of {{ ansible_facts['machine'] }} is {{ ansible_facts.default_ipv4.address }}
[root@ansible ~]# ansible-playbook play.yml

Ansible 事实作为变量注入
在Ansible2.5 之前,事实是作为前缀为字符串**ansible_**的单个变量注入,而不是作为
ansible_facts 变量的一部分注入。例如,ansible_facts[ ‘distribution ’] 事实会被称为
ansible_distribution。
Ansible 事实名称对比
Ansible----deepin_第1张图片

目前,Ansible 同时识别新的事实命名系统(使用ansible_facts)和旧的2.5 前“作为单独变量注入的事实”命名系统。

如果将Ansible 配置文件的**[default]部分中inject_facts_as_vars 参数设置为False**,可关闭旧命名系统。默认设置目前为True。

在未来的版本中旧的写法可能会默认更改为False,所有建议用新的形式

[root@ansible ~]# vim /etc/ansible/ansible.cfg
...
# inject_facts_as_vars = True
...

关闭事实收集
关闭收集事实的原因可能有:
不准备使用任何事实
希望加快play 速度
希望减小play 在受管主机上造成的负载
受管主机因为某种原因无法运行setup 模块(如:受管主机可能是路由器、交换机等设
备)
需要安装一些必备软件后再收集事实
将gather_facts 关键字设置为no 可以禁用setup

---
- hosts: all
gather_facts: no
tasks:
- name: Prints various Ansible facts
debug:
msg: >
The machine and ipv4 address of {{ ansible_facts['machine '] }}
is {{ ansible_facts.default_ipv4.address }}
[root@ansible ~]# ansible-playbook play.yml

即使play 设置了gather_facts: no,也可以随时通过运行使用setup 模块的任务来手动收集事实

---
- hosts: all
  gather_facts: no
  tasks:
  - name: start setup
      setup:
  - name: Prints various Ansible facts
      debug:
        msg: >
            The machine and ipv4 address of {{ ansible_facts['machine'] }} is {{ ansible_facts.default_ipv4.address }}
[root@ansible ~]# ansible-playbook play.yml

创建自定义事实
除了使用系统捕获的事实外,我们还可以自定义事实,并将其本地存储在每个受管主机
上。
这些事实整合到setup 模块在受管主机上运行时收集的标准事实列表中。

它们让受管主机能够向Ansible 提供任意变量,以用于调整play 的行为\

自定义事实可以在静态文件中定义,格式可为INI 文件或采用JSON。它们也可以是生
成JSON 输出的可执行脚本,如同动态清单脚本一样

默认情况下,setup 模块从各受管主机的**/etc/ansible/facts.d 目录下的文件和脚本中加载自定义事实。各个文件或脚本的名称必须以.fact**结尾才能被使用。

动态自定义事实脚本必须输出JSON 格式的事实,而且必须是可执行文件。
使用INI 格式编写自定义事实,INI 格式的自定义事实文件包含由一个部分定义的顶层值,后跟用于待定义的事实的键值对

[webserves]
web1 = 192.168.11.110
web2 = 192.168.66.66

使用JSON 格式编写自定义事实,JSON 数据可以存储在静态文本文件中,或者通过可执行脚本输出到标准输出

"webserves": {
"web1": "192.168.11.110",
"web2": "192.168.66.66"
}

自定义事实文件不能采用playbook 那样的YAML 格式。JSON 格式是最为接近的等效格式
自定义事实由setup 模块存储在ansible_facts.ansible_local 变量中。事实按照定义它们的文件的名称来整理

---
- hosts: all
  tasks:
  - name: Prints various Ansible facts
      debug:
        var: ansible_facts['ansible_local']['cwt']['webserves']['web1']

[root@ansible ~]# ansible-playbook play.yml

playbook 剧本的编写实例精讲
实例: 包含多个play 的playbook
vim tow.yml

---
- name: Execute NODE1 #一个play
  hosts: node1 #执行的主机组名
  tasks: #任务列表
    - name: install http #描述任务
      apt: #模块名
        name: apache2 #安装的包名
        state: present #允许安装
    - name: Start service httpd, if not started #描述任务
      service: #模块名
        name: apache2 #启动的服务名
        state: started #启动的服务
- name: Execute NODE2
  hosts:
    - node2
  tasks:
     - name: install gcc
       apt:
         name: gcc
         state: present

执行:

ansible-playbook --syntax-check tow.yml #检查yml 语法
ansible all -m shell -a "apt update" #执行更新apt 源
ansible-playbook tow.yml #运维playbook 的yml 文件
curl 192.168.200.11 //验证可以访问到#验证

实例:循环
同时启动ssh 和apache
vim Circulates.yml

---
- name: xhlx
  hosts: node1
  tasks:
    - name: sshd and apache2 are running
      service:
        name: "{{ item }}"
        state: started
     loop:
       - sshd
       - apache2
ansible-playbook --syntax-check Circulates.yml
ansible-playbook Circulates.yml

实例:变量及条件判断
变量my_service 已定义,如果定义了,安装相应的软件包,没定义则跳过、也不会报错
vim tjpd.yml

---
- name: panduan
  hosts: all
  vars: #定义变量名
  my_service: apache2
  tasks:
    - name: "{{ my_service }} package is installed"
      apt:
        name: "{{ my_service }}"
      when: my_service is defined

判断路径:

- hosts: all
  remote_user: root
  gather_facts: no
  vars:
     testpath1: "/etc"
     testpath2: "/haha"
  tasks:
    - debug:
         msg: "directory"
      when: testpath1 is directory
    - debug:
         msg: "file"
      when: testpath2 is file

你可能感兴趣的:(ansible,ssh,python,运维)