【ansible】管理变量与事实详解

目录

管理变量与事实

一,变量

1,变量命名

2,变量优先级(高--低)

3,命令行引用

4, 引用playbook中的变量

5, 在主机清单中定义变量

6, 在自定义变量文件中定义变量

7,在目录中定义清单变量

8,使用数组作为变量

9,系统变量register

二,使用ansible vault加密文件

1,创建加密文件(create)

2,查看加密文件内容(view)

3,使用文件内容作为加密密码(--vault-password-file=密码文件)

4,解密加密文件(decrypt)

5,将加密文件解密到指定文件中(--output 指定文件)

6,更改加密文件的密码(rekey)

7,使用文件更改加密文件的密码(rekey   --new-vault-password-file=密码文件)

8,通过剧本加载加密文件(--vault-id @prompt )

三,管理事实

1,描述ansible事实

2,ansible事实实例

3,受管主机收集事实的方式

4,接收事实收集的方法

5,关闭事实收集

6,创建自定义事实


管理变量与事实

事实:主机上的默认定义的变量信息

一,变量

1,变量命名

变量名称必须是以字母开头,并且只能含有字母、数字和下划线。

2,变量优先级(高--低)

  • (1)全局范围:从命令行或ansible配置设置的变量
  • (2)play范围:在play和相关结构中设置的变量
  • (3)主机范围:由清单、事实收集或注册的任务,在主机和个别主机上设置的变量
  • 命令行定义变量--> yaml文件中的变量(vars_file  --->   vars)--->主机清单中单独定义主机变量--->主机清单公共变量

 

3,命令行引用

变量要用两个花括号引起来,变量作为键值对的值必须用引号引起来

(1)在/day04/playbook目录下创建var_test.yml文件

此时的受控主机上node1没有vsftp软件包

[root@node1 ~]# rpm -qa | grep vsftpd

(2)在var_test.yml文件中安装软件包,在命令行把要安装的软件包传入到剧本中的变量

- name: play1

  hosts: all

  tasks: 装包

    - name: task1

      yum:

        name: "{{ pkname }}"

        state: present

(3)在命令行给变量传入变量值,并执行var_test.yml文件,在node1上安装vsftpd

[root@server playbook]# ansible-playbook -e "pkname=vsftpd" var_test.yml

(4)此时在node1主机上查看vsftpd,已经安装成功

[root@node1 ~]# rpm -qa | grep vsftpd

4, 引用playbook中的变量

(1)此时的node1主机上有vsftpd和bind

[root@node1 ~]# rpm -qa | grep vsftpd

[root@node1 ~]# rpm -qa | grep bind

(2) 在var_test.yml中定义变量 vars

在var_test.yml中定义vars

---

- name: play1

  hosts: test1

  vars:

    pkname: vsftpd

  tasks:

    - name: task1

      yum:

        name: "{{ pkname }}"

        state: absent

(3)在命令行定义变量为bind的同时在playbook中定义变量为vfstpd

[root@server playbook]# ansible-playbook -e "pkname=bind" var_test.yml

(4)执行完命令后,再次查看bind和vfstpd包,发现bind被删除了,但是vfstpd包还在

         说明命令行中变量的优先级大于yaml文件中变量的优先级

[root@node1 ~]# rpm -qa | grep bind

[root@node1 ~]# rpm -qa | grep vsftpd

注: 引用变量中间有无空格都可以,变量用作开始一个值得第一元素时,必须使用引号防止ansible将变量引用视为yaml字典的开头。

5, 在主机清单中定义变量

(1)查看此时匹配到的主机清单文件

[root@server playbook]# ansible --version

(2)此时的node1主机与node2主机都有httpd与vsftpd

[root@node1 ~]# rpm -qa | grep httpd
[root@node1 ~]# rpm -qa | grep vsftpd

[root@node2 ~]# rpm -qa | grep vsftpd
[root@node2 ~]# rpm -qa | grep httpd

 

(3)打开主机清单文件,定义变量,对单个主机node1卸载httpd;对主机组node1与node2卸载vsftpd

node1 pkname=httpd

[test]

node1

node2

[test:vars]

pkname=vsftpd

(4)在剧本中定义变量

---

- name: play1

  hosts: all

#  vars:

#    pkname: vsftpd

  tasks:

    - name: task1

      yum:

        name: "{{ pkname }}"

        state: absent

(5)执行剧本var_test.yml

[root@server playbook]# ansible-playbook var_test.yml

(6)此时在node1主机上查看httpd与vsftpd;发现httpd已经被卸载了

[root@node1 ~]# rpm -qa | grep httpd
[root@node1 ~]# rpm -qa | grep vsftpd

(7)在node1主机上查看httpd与vsftpd;发现vsftpd已经被卸载了

[root@node2 ~]# rpm -qa | grep httpd
[root@node2 ~]# rpm -qa | grep vsftpd

说明主机清单中的变量优先匹配单个主机变量,其次匹配主机组中的变量,最后匹配嵌套主机组定义的变量值

6, 在自定义变量文件中定义变量

1,导入var_files文件定义变量

(1)此时的node1主机与node2主机上均存在bind

[root@node2 ~]# rpm -q bind

[root@node1 ~]# rpm -q bind

(2)在packages文件中定义变量(按照yml的语法格式定义)

[root@server playbook]# vim packages

pkname: bind

(3)把变量文件vars_files导入var_test.yml剧本中

---

- name: play1

  hosts: all

#  vars:

#    pkname: vsftpd

  vars_files:

    - packages

  tasks:

    - name: task1

      yum:

        name: "{{ pkname }}"

        state: absent

(4)执行剧本文件var_test.yml

[root@server playbook]# ansible-playbook var_test.yml

(5)此时在node1与node2主机上查看bind,发现已经被卸载

[root@node1 ~]# rpm -q bind

[root@node2 ~]# rpm -q bind

2,定义变量信息的同时导入变量文件

(1)此时的node1主机与node2主机上均没有bind与httpd

[root@node1 ~]# rpm -q bind
[root@node1 ~]# rpm -q httpd

[root@node2 ~]# rpm -q bind
[root@node2 ~]# rpm -q httpd

(2)在var_test.yml文件中定义变量使其安装httpd并导入变量文件packages

---

- name: play1

  hosts: all

  vars_files:

    - packages

  vars:

    pkname: httpd

  tasks:

    - name: task1

      yum:

        name: "{{ pkname }}"

        state: present

---

- name: play1

  hosts: all

  vars_files:

    - packages

  vars:

    pkname: httpd

  tasks:

    - name: task1

      debug:

        msg: pkname={{ pkname }}

(3)编辑变量文件packages

[root@server playbook]# vim packages

pkname: bind

(3)执行var_test.yml剧本文件

[root@server playbook]# ansible-playbook var_test.yml

(8)在node1主机上与node2主机上查看httpd与bind;发现bind已经安装;

[root@node1 ~]# rpm -q httpd
[root@node1 ~]# rpm -q bind

[root@node2 ~]# rpm -q httpd
[root@node2 ~]# rpm -q bind

说明yaml文件中的变量(vars_file  --->   vars)

总的来说:命令行定义变量--> yaml文件中的变量(vars_file  --->   vars)--->主机清单中单独定义主机变量--->主机清单公共变量

3,一次性安装软件包httpd;vsftps;firewalld

(1)可以使用下列方法一次性传入多个参数

---

- name: play1

  hosts: all

  vars:

    pkname:

      - httpd

      - vsftpd

      - firewalld

  tasks:

    - name: task1

      debug:

        msg: pkname={{ pkname }}

(2)执行剧本文件var_test.yml

[root@server playbook]# ansible-playbook var_test.yml

注意:这种做法存在一些缺点,它是清单文件更难处理,在同一文件中混合提供了主机和变量信息,而且采用的也是过时的语法。

使用目录填充主机和组变量-----重要!!!

7,在目录中定义清单变量

建议的做法是使用host_vars和group_vars目录定义清单变量,而不直接在清单文件中定义。

---

- name: play1

  hosts: all

  tasks: 

    - name: task1

      debug:

        msg: pkname={{ pkname }}

(1)创建host_vars主机的变量目录和group_vars主机组的变量目录   目录定义清单变量

[root@server playbook]# mkdir host_vars group_vars

(2)在主机目录下面创建主机变量文件(针对node1主机创建变量文件)

[root@server playbook]# vim host_vars/node1

pkname: httpd

[root@server playbook]# mkdir group_vars/test
[root@server playbook]# vim group_vars/test/var.yml

pkname: vsftpd

(3)查看创建的目录的结构

[root@server playbook]# tree

(4)执行var_test.yml剧本文件

[root@server playbook]# ansible-playbook var_test.yml

(1)创建host_vars/node2目录并编辑文件var.yml

[root@server playbook]# mkdir host_vars/node2
[root@server playbook]# vim host_vars/node2/var.yml

pkname: mod_ssl

(2)查看目录及文件的结构

[root@server playbook]# tree

(3)执行剧本文件var_test.yml

[root@server playbook]# ansible-playbook var_test.yml

 

 

 

8,使用数组作为变量

 数组(Array)是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数 组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 这些有序排列的同类数据元素的集合称为数组。

数组是用于储存多个相同类型数据的集合。

 

 

(1)创建目录

[root@server ~]# mkdir /day05/var_test -pv

 

 

(2)在目录/day05/var_test下创建文件ansible.cfg与inventory文件

[root@server var_test]# cp /day04/playbook/ansible.cfg .
[root@server var_test]# cp /day04/playbook/inventory .

 

 

 (3)查看ansible.cfg文件以及inventory文件

[root@server var_test]# cat ansible.cfg

[defaults]

inventory=./inventory

[root@server var_test]# cat inventory

node1

[test]

node1

node2

 

 

(4)在目录/day05/var_test下面创建playbook.yml文件

 [root@server var_test]# vim playbook.yml

  

变量引用方法一:

---

- name: play1

  vars:

    student:

      zhangsan:

        yuwen: 80

        shuxue: 81

        yingyu: 79

      lisi:

        yuwen: 90

        shuxue: 91

        yingyu: 92

  hosts: test

  tasks:

    - name: task1

      debug:

        msg: 语文成绩是:{{ student.zhangsan.yuwen }}

 

 

(5)执行剧本

[root@server var_test]# ansible-playbook playbook.yml

 

变量引用方法二:

---

- name: play1

  vars:

    student:

      zhangsan:

        yuwen: 80

        shuxue: 81

        yingyu: 79

      lisi:

        yuwen: 90

        shuxue: 91

        yingyu: 92

  hosts: test

  tasks:

    - name: task1

      debug:

        msg: 数学成绩是:{{ student['lisi']['shuxue'] }} 

 

 

执行剧本playbook.yml

[root@server var_test]# ansible-playbook playbook.yml

 

方法一:

国家:

        省份:

                城市:

                        县:

                                镇:

方法二:

{{ 国家.省份.城市.县.镇 }}

方法三:

{{ 国家['省份']['城市']['县']['镇'] }}

msg  var  引用变量的区别:

var后面直接跟变量,不需要双引号与花括号

var:  student['lisi']['shuxue']

msg后面需要花括号引用变量

msg: {{ student['lisi']['shuxue'] }}

9,系统变量register

使用register已注册变量捕获命令输出

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

注:msg var的区别msg 引用变量{{ }} var后面直接跟变量名名

eg:

 

 

(1)在目录/day05/var_test下面编辑文件playbook1.yml

---

- name: play1

  hosts: test

  tasks:

    - name: task1

      copy:

        dest: /file

        content: "this is a file\n"

 

(2)执行剧本并没有显示详细信息

[root@server var_test]# ansible-playbook playbook1.yml

 

(3)使用register捕获详细信息存储到results变量中,并在debug模块捕获并显示

---

- name: play1

  hosts: test

  tasks:

    - name: task1

      copy:

        dest: /file

        content: "this is a file\n"

      register: results

    - name: task2

      debug:

        msg: "{{ results }}"

 

 

(4)执行剧本playbook1.yml可以看到捕获到的详细信息如下所示

[root@server var_test]# ansible-playbook playbook1.yml

 

(5)显示上面捕获到的详细信息中的size的信息

---

- name: play1

  hosts: test

  tasks:

    - name: task1

      copy:

        dest: /file

        content: "this is a file\n"

      register: results

    - name: task2

      debug:

        msg: "{{ results }}"

      register: cmd_results

    - name: task3

      debug:

        msg: "{{ cmd_results.msg.size }}"

 

 (6)此时执行剧本playbook1.yml就能看到task3捕获到的size大小

 

 

 

二,使用ansible vault加密文件

 ansible可能需要访问密码或者API秘钥等敏感数据,以便能配置受管主机。通常,此信息可能以纯文本形式存储在清单变量或其他ansible文件中。但若如此,任何有权访问ansible文件的用户或存储这些ansible文件的版本控制系统都能访问如此敏感数据。这显然存在安全风险。

使用ansible随附的ansible vault 可以加密和解密任何由ansible使用的结构化数据文件。若要使用ansible vault,可通过一个名为ansible-vault的命令行共计创建、编辑、加密、解密和查看文件。Ansible vault可以加密任何由ansible使用的结构化数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者ansible角色中定义的变量。

注:ansible-vault并不实施自有的加密函数,而是使用外部python工具。文件通过利用AES256的对称加密(将密码用作机密秘钥)加以保护,这种方式并未得到第三方正式审核。

 

创建加密文件的常用参数:

creat:  创建加密文件

decrypt:   解密

edit:    进入编辑

view:  显示文件信息

encrypt:   加密

encrypt_string:  加密字符串

rekey: 重置

 

在目录/day05/playbook下面创建playbook2.yml文件

---

- name: play1

  hosts: test

  vars_files:

    - user_var.yml

  tasks:

    - name: task1

      user:

        name: "{{ username }}"

        password: "{{ pass }}"

        state: present

 

 

 

 

 

1,创建加密文件(create)

(1)创建加密文件user_var.yml并输入加密文件的密码

[root@server var_test]# ansible-vault create user_var.yml

 

(2)生成加密后的密码

[root@node1 ~]# python3
>>> import crypt
>>> crypt.crypt('123456')

'$6$K37gjva7lG7U4Z0N$.F9RPUC4iHRtH35P/4Y2RhoYm47dwnQeGcNTMi/6eFs8eQYS.WtEkWKP0uWVaIQzl5nUADw3EIbYdXsL3WSJ90'

 

 

(3) 在加密文件中定义变量

username: xiao1

pass: '$6$K37gjva7lG7U4Z0N$.F9RPUC4iHRtH35P/4Y2RhoYm47dwnQeGcNTMi/6eFs8eQYS.WtEkWKP0uWVaIQzl5nUADw3EIbYdXsL3WSJ90'

 

(4)输入密码后会利用默认的编辑器vi打开文件进行编辑。也可通过EDITOR环境变量更改默认编辑器。

例如:将默认编辑器设置为vim,则设置export EDITOR=vim

[root@server var_test]# export EDITOR=vim

 

 

(5)此时查看问价user_var.yml会看到文件已经被加密

[root@server var_test]# cat user_var.yml

 

 

2,查看加密文件内容(view)

(1)输入加密文件的密码查看加密文件user_var.yml的内容

[root@server var_test]# ansible-vault view user_var.yml

 

 

 

 

 

3,使用文件内容作为加密密码(--vault-password-file=密码文件)

(1)创建文件p1

[root@server var_test]# vim p1

 

 

(2) 将p1文件的内容作为加密的密码

[root@server var_test]# ansible-vault create --vault-password-file=p1 v.yml

 

 

 

(3)查看加密文件v.yml文件的内容,用p1文件自动输入密码

[root@server var_test]# ansible-vault view --vault-password-file=p1 v.yml

 

 

 

4,解密加密文件(decrypt)

(1)对加密文件user_var.yml进行解密

[root@server var_test]# ansible-vault decrypt user_var.yml

 

(2)此时查看文件user_var.yml会看到文件未被加密的内容

[root@server var_test]# cat user_var.yml

 

 

 

 

5,将加密文件解密到指定文件中(--output 指定文件)

(1)将加密文件user_var.yml解密到vvv.yml文件中

[root@server var_test]# ansible-vault decrypt user_var.yml --output vvv.yml

 

(2)查看文件vvv.yml的内容

[root@server var_test]# cat vvv.yml

 

(3)注意:此时的文件user_var.yml并未被解密,

[root@server var_test]# cat user_var.yml

 

 

 

6,更改加密文件的密码(rekey)

将加密文件user_var.yml的密码由123456改为111111

[root@server var_test]# ansible-vault rekey user_var.yml

Vault password:                              输入原来的密码

New Vault password:                     输入修改后的密码

Confirm New Vault password:      再次确认密码

Rekey successful

 

 

 

7,使用文件更改加密文件的密码(rekey   --new-vault-password-file=密码文件)

(1)将加密文件v.yml 文件的密码由p1文件的123456改为p2文件的111111

[root@server var_test]# vim p2

111111

 

(2)可以手动输入旧密码确认

[root@server var_test]# ansible-vault rekey --new-vault-password-file=p2 v.yml

 

 

(3)也可以通过文件p1确认旧密码

[root@server var_test]# ansible-vault rekey --vault-password-file=p1 --new-vault-password-file=p2 v.yml

 

 

 

8,通过剧本加载加密文件(--vault-id @prompt )

(1)可以看到playbook2.yml文件中需要加载文件user_var.yml;

[root@server var_test]# vim playbook2.yml

 

(2)而user_var.yml文件为加密文件

[root@server var_test]# cat user_var.yml

 

 

(3)此时,剧本无法直接加载文件playbook2.yml

[root@server var_test]# ansible-playbook playbook2.yml

 

 

(4)需要输入文件的密码才能加载文件,执行剧本文件

[root@server var_test]# ansible-playbook --vault-id @prompt playbook2.yml

Vault password (default):            需要手动输入文件user_var.yml的密码

 

(5)查看剧本的执行结果

[root@node1 ~]# id xiao1

 

 

 

 

 

 

 

三,管理事实

1,描述ansible事实

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

 受管主机的事实有(主机名称、内核版本、网络接口、ip地址、操作系统版本、各种变量、CPU数量、提供的或可用的内存、可用磁盘等)

 借助事实我们可以方便检索主机的状态,并根据状态确定要执行的操作。

例如:

1.根据不同的内核版本事实运行条件任务,以此来重新启动服务。

2.根据事实报告的可能内存情况来定义mysql配置文件。

3.可根据事实的值设置配置文件中使用的ipv4的地址。

 

 

 

2,ansible事实实例

  • Ansible2.5之前,事实是作为前缀为字符串ansible_的单个变量注入,而不是作为ansible_facts变量的一部分注入
  • ansible_facts['distribution']事实会被称为ansible_distribution

ansible_facts形式

旧事实变量形式

ansible_facts['hostname']

ansible_hostname

ansible_facts['fqdn']

ansible_fqdn

ansible_facts'default_ipv4'

ansible_default_ipv4['address']

ansible_facts['interfaces']

ansible_interfaces

ansible_facts'devices''partitions'['size']

ansible_devices'vda''vda1'

ansible_facts'dns'

ansible_dns['nameservers']

ansible_facts['kernel']

ansible_kernel

ansible事实的事例

事实

变量

短主机名

ansible_facts['hostname']

完全限定域名

ansible_facts['fqdn']

主机ipv4地址

ansible_facts'default_ipv4' ==== ansibe_facts.default_ipv4.address

网络接口名称列表

ansibel_facts['interfaces']

/dev/vda1磁盘分区大小

ansible_facts'devices''partitions'['size']

DNS服务器列表

ansible_facts'dns' ===ansible_facts'dns'

当前运行的内核版本

ansible_facts['kernel']

 

 

1,显示短的主机名

  msg: "{{ ansible_facts.hostname }}"

 

执行剧本playbook3.yml文件,可以看到短的主机名

[root@server var_test]# ansible-playbook playbook3.yml

 

 

2,显示长的主机名

 msg: "{{ ansible_facts.fqdn }}"

 

执行剧本playbook3.yml文件,可以看到长的主机名

[root@server var_test]# ansible-playbook playbook3.yml

 

 

 

 

3,显示ipv4地址

 msg: "{{ ansible_facts.default_ipv4.address }}"

 

执行剧本playbook3.yml文件,可以看到ipv4的地址

[root@server var_test]# ansible-playbook playbook3.yml

 

 

 

4,显示网络接口名称列表

 msg: "{{ ansible_facts.interfaces }}"

 

执行剧本playbook3.yml文件,可以看到网络接口名称列表

[root@server var_test]# ansible-playbook playbook3.yml

 

 

 

 

3,受管主机收集事实的方式

1. setup模块(变量信息  内置系统中的变量信息)

(1)系统的默认值,不能手动修改

[root@server var_test]# ansible node1 -m setup | less

  

(2)编辑playbook3.yml文件

[root@server var_test]# vim playbook3.yml

(3)过滤出ipv4的地址的值

匹配事实时,可以省略第一个相同的单词

---

- name: play1

  hosts: node1

  gather_facts: yes  # 默认开启接收事实

  tasks:

    - name: task1

      debug:

        msg: "{{ ansible_facts.default_ipv4.address }}"

(4)执行剧本playbook3.yml,可以看到过滤出来的ipv4地址为192.168.206.111

[root@server var_test]# ansible-playbook playbook3.yml

4,接收事实收集的方法

方法一:gather_ facts:  yes

方法二:

- name: task0

      setup:

5,关闭事实收集

gather_facts: no

执行剧本文件playbook3.yml

[root@server var_test]# ansible-playbook playbook3.yml

如果不想从fact中获取变量,或者说整个playbook当中都没有使用到fact变量,可以通过如下方法关闭fact以提升执行效率:

也可以在ansible.cfg中添加如下配置:

[defaults]

gathering = explicit (明确的)

ansible的配置文件中可以修改'gathering'的值为smart、implicit或者explicit。

(1)smart 表示默认收集facts,但facts已有的情况下不会收集,即使用缓存facts;

(2)implicit 表示默认收集facts ;

(3)explicit 则表示默认不收集;

6,创建自定义事实

默认情况下setup模块从受管主机/etc/ansible/facts.d目录下的文件和脚本中加载自定义事实。各个文件名必须以.fact结尾才能使用。动态自定义事实脚本必须输出JSON格式的事实,而且必须是可执行文件。

 

INI和JSON格式编写的静态自定义事实文件。INI格式的自定义事实文件包含由一部分定义的顶层值,后跟用于待定义事实的键值对。

 

(1)在受控主机node1上创建目录/etc/ansible/facts.d并在此目录下创建abc.fact结尾的文件

[root@node1 ~]# mkdir /etc/ansible/facts.d -pv

 

 

(2)在目录/etc/ansible/facts.d下面创建文件abc.fact

[root@node1 facts.d]# touch abc.fact

 

(3)编辑文件abc.fact内容

[users]

user1 = joe

user2 = jane

 

 

(4)在控制端主机server上捕获node1主机的uers1

msg: "{{ ansible_facts.ansible_local.abc.users.user1 }}"

 

 

(5)执行剧本playbook3.yml查看信息捕获到的use1的信息

[root@server var_test]# ansible-playbook playbook3.yml

 

 

(6)过滤出ansible_local对象下所有的值

[root@server var_test]# ansible node1 -m setup -a 'filter=ansible_local'

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值