ansible管理变量、机密和事实

1.管理变量

1.1Ansible概述

Ansible支持利用变量来存储值,并在Ansible项目的所有文件中重复使用这些值。这可以简化项目的创建和维护,并减少错误的数量。

通过变量,可以轻松地在Ansible项目中管理给定环境的动态值。例如,变量可能包含下面这些值:

① 要创建的用户
② 要安装的软件包
③ 要重新启动的服务
④ 要删除的文件
⑤ 要从互联网检索的存档

1.2变量命名

变量的名称必须以字母开头,并且只能包含字母、数字和下划线。
无效和有效的Ansible变量名称示例:

无效的变量名称有效的变量名称
web serverweb_server
remote.fileremote_file
1st filefile_1 / file1
remoteserver$1remote_server_1 / remote_server1

1.3变量定义

可以在Ansible项目中的多个位置定义变量。不过,这些变量大致可简化为三个范围级别:

全局范围:从命令行或Ansible配置设置的变量
Play范围:在play和相关结构中设置的变量
主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
如果在多个xeklh定义了相同名称的变量,则采用优先级别最高的变量。
优先级:全局范围 > play范围 > 主机范围(主机或主机组) 由清单定义的变量将被playbook定义的变量覆盖,playbook定义的变量将被命令行中定义的变量覆盖。

1.4 playbook中的变量

变量在Ansible Playbook中发挥着重要作用,因为它们可以简化playbook中变量数据的管理。

在Playbook中定义并使用变量

编写playbook时,可以定义自己的变量,然后在任务中调用这些值。例如,名为web_package的变量可以使用值httpd来定义。然后,任务可以使用yum模块调用该变量来安装httpd软件包。

Playbook变量可以通过多种方式定义。一种常见的方式是将变量放在playbook开头的vars块中:

---
- hosts: 192.168.120.130
  vars:                  //vars块下定义变量
    package_name: httpd    //变量为httpd,变量命名为package_name(可自由命名)
  tasks:
    - name: install httpd
      yum:
        name: "{{ package_name }}"     //此处双引号里两个大括号里写给变量的命名,并且变量前后都要空一格
        state: present
:wq!
...检查语法和测试执行过程是否成功👇
[root@king playbook]# ansible-playbook --syntax-check play.yml 

playbook: play.yml
[root@king playbook]# ansible-playbook -C play.yml 

PLAY [192.168.120.130] *********************************************************

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

TASK [install httpd] ***********************************************************
changed: [192.168.120.130]

PLAY RECAP *********************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

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

[root@king ~]# yum -y install tree
[root@king playbook]# mkdir vars
[root@king playbook]# vim vars/vars.yml  //vars变量文件格式必须是yml

package_name: httpd  //给变量命名
:wq!
[root@king playbook]# tree
.
├── play.yml  //vars和写playbook内容文件同级
└── vars     //创建vars目录以免有更多yml变量配置文件
    └── vars.yml

1 directory, 2 files

---
- hosts: 192.168.120.130
  vars_files:
    - vars/vars.yml   //写变量文件位置
  tasks:
    - name: install httpd
      yum:
        name: "{{ package_name }}"  //填写变量命名
        state: present
:wq!
...语法检测和测试执行过程正常👇
[root@king playbook]# ansible-playbook --syntax-check play.yml 

playbook: play.yml
[root@king playbook]# ansible-playbook -C play.yml 

PLAY [192.168.120.130] *********************************************************

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

TASK [install httpd] ***********************************************************
changed: [192.168.120.130]

PLAY RECAP *********************************************************************
192.168.120.130            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

1.5主机变量和主机组变量

直接应用于主机的清单变量分为两在类:
主机变量:应用于特定主机
主机组变量:应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高。

定义主机和主机组的变量的首选做法是在与清单文件或目录相同的工作目录中,创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。
建议的做法是使用host_varsgroup_vars目录定义清单变量,而不直接在清单文件中定义它们。

<1>主机变量

[root@king ~]# mkdir Game   //创建项目目录名
[root@king ~]# cp /etc/ansible/ansible.cfg /root/Game //把ansible配置文件复制到Game项目目录里
[root@king ~]# cd Game/
[root@king Game]# mkdir file  //创建存放项目其它文件位置
[root@king Game]# touch inventory  //创建清单文件
[root@king Game]# mkidr host_vars //创建主机变量文件(单数host)
[root@king Game]# touch playbook.yml   //创建以yaml格式写playbook文件,以.yml文件名结尾
[root@king Game]# vim inventory  //先编辑清单文件,添加IP(此处不写密码,密码作为变量使用)
192.168.120.130
:wq!
[root@king host_vars]# vim 192.168.120.130  //使用主机名来命名,更直观便捷

ansible_password: admin123   //以yaml格式写变量内容
:wq!
[root@king Game]# vim ansible.cfg  //修改内容
...
#inventory      = /etc/ansible/hosts
inventory       =/root/Game/inventory  //修改在项目配置文件里清单文件路径
....
:wq!
[root@king Game]# tree
.
├── ansible.cfg
├── file
├── host_vars
│   └── 192.168.120.130
├── inventory
└── playbook.yml
[root@king Game]# ansible all -m ping
192.168.120.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
[root@king Game]# ansible all -i inventory -m ping
192.168.120.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
可以ping成功,表示变量设置成功!

<2>主机组变量

[root@king Game]# mkdir group_vars  //在项目中创建主机组变量
[root@king Game]# vim inventory    //编辑清单文件
[root@king Game]# cat inventory 
[hosts]
192.168.120.130
192.168.120.131
[root@king group_vars]# vim hosts  //在主机组目录变量下用清单文件中主机组名字来命名
[root@king Game]# cat group_vars/hosts 
ansible_password: admin123   //密码为变量
[root@king Game]# tree
.
├── ansible.cfg
├── file
├── group_vars
│   └── hosts
├── host_vars
├── inventory
└── playbook.yml

3 directories, 5 files

[root@king Game]# ansible hosts -i inventory -m ping
192.168.120.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.120.131 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

可以ping成功,表示变量设置成功!

1.6从命令行覆盖变量

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

当需要覆盖一次性运行的playbook的变量的已定义值时,额外变量非常有用。例如:
使用 -e+“变量内容”,每执行一次都要加上-e参数

[root@king Game]# mv group_vars/hosts /tmp/
[root@king Game]# tree //此时主机变量和组变量下没有定义变量
.
├── ansible.cfg
├── file
├── group_vars
├── host_vars
├── inventory
└── playbook.yml

3 directories, 3 files
[root@king Game]# ansible all -i inventory -e "ansible_password=admin123" -m ping
192.168.120.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.120.131 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
[root@king playbook]# ansible-playbook play.yml -e "package_name=httpd"

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

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

以下playbook演示了如何为调试用途捕获命令输出结果,运行该playbook时,debug模块用于将install_result注册变量的值转储到终端:

[root@king playbook]# vim play.yml 
---
- name: install wget
  hosts: 192.168.120.130
  tasks:
    - name: install wget
      yum:
        name: wget
        state: present
      register: result    //register用来注册变量  
    - debug: var=result //注册变量的值转储到终端显示过程结果
:wq!
[register与yum模块同级;- debug与模块上面- name同级]
[root@king playbook]# ansible-playbook play.yml 

PLAY [install wget] ************************************************************

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

TASK [install wget] ************************************************************
changed: [192.168.120.130]

TASK [debug] *******************************************************************
ok: [192.168.120.130] => {
    "result": {
        "changed": true,
        "changes": {
            "installed": [
                "wget"
            ]
        },
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package wget.x86_64 0:1.14-18.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package        Arch             Version                  Repository       Size\n================================================================================\nInstalling:\n wget           x86_64           1.14-18.el7              local           547 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 547 k\nInstalled size: 2.0 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : wget-1.14-18.el7.x86_64                                      1/1 \n  Verifying  : wget-1.14-18.el7.x86_64                                      1/1 \n\nInstalled:\n  wget.x86_64 0:1.14-18.el7                                                     \n\nComplete!\n"
        ]
    }
}

PLAY RECAP *********************************************************************
192.168.120.130            : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
检查已经安装成功:
[root@king ~]# ansible all -m shell -a 'yum list installed|grep wget'
192.168.120.130 | CHANGED | rc=0 >>
wget.x86_64                           1.14-18.el7                      @local   

2.管理变量

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

2.1ansible vault创建加密文件

两种设置加密文件的方式:
① 要创建新的加密文件,可使用ansible-vault create +新文件名 命令。该命令将提示输入新的vault密码,并且生成密码文件,然后利用默认编辑器vi打开文件。不能直接用cat来查看加密的变量文件里内容:

[root@king playbook]# ls
play.yml  vars
[root@king playbook]# ansible-vault create test.yml  //会输入两次密码,并且会进入vi编辑里输入受控主机的密码
New Vault password: 
Confirm New Vault password: 

ansible_password: admin123
:wq!
[root@king playbook]# tree
.
├── play.yml
├── test.yml  //创建的密码文件yaml格式写入
└── vars
    └── vars.yml

1 directory, 3 files
[root@king playbook]# cat test.yml  //查看是一个加密文件内容(只能看到的是乱码)
$ANSIBLE_VAULT;1.1;AES256
34343932623565353738346566326233643937613764643032343837656634643238623262313863
3434323130363963663633393863313533643334306235620a396264613161353933313263613862
32333131663333366531646265636663316637373063346432633830303031353263356434373431
6565363034326234620a373737653663613836666139636637656265356635323136383839326637
66393064663338623031373435643533356337653962323432356662376139623430

② 可以用vault密码文件来存储vault密码vault-password文件,不用通过标准输入途径输入vault密码。利用存储密码的文件对新生成的文件进行加密,可以直接查看到设置加密文件的密码,不能直接用cat来查看加密的变量文件里内容:

[root@king ~]# cd /Game/group_vars
[root@king group_vars]# vim vault-password  //存放vault密码的文件
//--vault-password-file=vault-password指定存放密码的文件
[root@king group_vars]# ansible-vault create --vault-password-file=vault-password test.yml
[root@king group_vars]# ls
test.yml  vault-password
[root@king group_vars]# cat vault-password  //可以直接查看到设置加密文件的密码是什么
123

2.2查看加密文件里内容

可以使用ansible-vault view filename命令查看Ansible Vault加密的文件内容,而不必打开它进行编辑,查看时需要输入加密文件的加密密码:

[root@king group_vars]# ansible-vault view test.yml 
Vault password: 123  //输入设置的密码
ansible_password: admin123

2.3编辑现有加密文件内容

要编辑现有的加密文件,Ansible Vault提供了ansible-vault edit filename命令。edit子命令始终重写文件,因此只应在进行更改时使用它。要查看文件的内容而不进行更改时,应使用view子命令:

[root@king group_vars]# ansible-vault edit test.yml 
Vault password: 123

ansible_password: admin123   //进入文件可进行更改

:wq!

2.4加密现有的文件

要加密已存在的文件,请使用ansible-vault encrypt filename命令。此命令可取多个欲加密文件的名称作为参数。

[root@king group_vars]# vim hosts
ansible_password: admin123
:wq!
[root@king group_vars]# ansible-vault encrypt hosts 
New Vault password:   //设置密码输入第一次
Confirm New Vault password:  //设置密码输入第二次
Encryption successful
[root@king group_vars]# cat hosts  //不能用cat直接查看加密文件
$ANSIBLE_VAULT;1.1;AES256
33616332306262616234393134383034646131666438376132346338376130633432666637393432
3665363562366432393135663332373632383937373566300a666263626163643636366437646135
37396338633066633835343936313530646639383563636165353736633139383437386637653233
6239393461636635620a303165613834393362346433346535346335373339326334623736616664
34336538363533353962653530623461366536316134393034656665613165303134

2.5解密现有的加密文件

现有的加密文件可以通过ansible-vault decrypt filename命令永久解密。

[root@king group_vars]# ansible-vault decrypt hosts  //解除加密文件给的密码
Vault password: 
Decryption successful
[root@king group_vars]# cat hosts   //解除后可直接用cat查看
ansible_password: admin123

在解密单个文件时,可使用–output选项设置新名称保存解除密码的文件内容,但是原来文件不会被解密,任处于加密文件:

[root@king group_vars]# ansible-vault encrypt hosts 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[root@king group_vars]# ansible-vault decrypt hosts --output=hosts_pass.yml
Vault password: 
Decryption successful
[root@king group_vars]# ls
hosts  hosts_pass.yml  test.yml  vault-password
[root@king group_vars]# cat hosts_pass.yml 
ansible_password: admin123
[root@king group_vars]# cat hosts  //查看原来文件内容
$ANSIBLE_VAULT;1.1;AES256
33363237613766316433306636643666316432613633656364393564613266306533393438356562
3836646565383138663861343936316665663462623265660a653262373130383439626534346562
32313430356363333563666636633036666434656533376234633061633436646563383639626536
6336623336336237310a386638353334363264653864333833616563336163633638323561343464
37373464333334613134343335643863323330356139316138303339343333316132

2.6更改加密文件的密码

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

[root@king group_vars]# ansible-vault rekey test.yml 
Vault password: 123  //老密码
New Vault password: 123456  //新密码
Confirm New Vault password: 123456 //新密码
Rekey successful
[root@king group_vars]# ansible-vault view test.yml 
Vault password: 123456  //输入更改后密码
ansible_password: admin123

2.7playbook和ansible vault联系

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

[root@king playbook]# ansible-vault encrypt play.yml 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[root@king playbook]# ansible-playbook play.yml 
ERROR! Attempting to decrypt but no vault secrets found

要为playbook提供vault密码,可使用–vault-id选项。例如,要以交互方式提供vault密码,请使用下例中所示的–vault-id @prompt:

[root@king playbook]# ansible-playbook --vault-id @prompt play.yml 
Vault password (default): 123  //输入加密文件密码

PLAY [install wget] ************************************************************

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

TASK [install wget] ************************************************************
ok: [192.168.120.130]

TASK [debug] *******************************************************************
ok: [192.168.120.130] => {
    "result": {
        "changed": false,
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "wget-1.14-18.el7.x86_64 providing wget is already installed"
        ]
    }
}

PLAY RECAP *********************************************************************
192.168.120.130            : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

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

[root@king playbook]# vim vault-password
[root@king playbook]# ansible-vault create --vault-password-file=vault-password test.yml 
[root@king playbook]# ansible-playbook --vault-password-file=vault-password test.yml 

PLAY [install wget] ************************************************************

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

TASK [install wget] ************************************************************
ok: [192.168.120.130]

PLAY RECAP *********************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

从Ansible2.4开始,可以通过ansible-playbook使用多个Ansible Vault密码。要使用多个密码,需要将多个–vault-id或–vault-password-file选项传递给ansible-playbook命令。

ansible-playbook --vault-id one@prompt --vault-id two@prompt site.yml

注意:@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中的文件外,也可对每一主机组或受管主机使用目录。这些目录可包含多个变量文件,它们都由该主机组或受管主机使用。
Playbook变量(与清单变量相对)也可通过Ansible Vault保护。敏感的playbook变量可以放在单独的文件中,此文件通过Ansible Vault加密,并能vars_files指令包含在该playbook中。这也是推荐做法,因为playbook变量的优先级高于清单变量。

如果需要在playbook中使用多个vault密码,请确保每个加密文件分配一个vaultID,并在运行playbook时输入具有该vaultID的匹配密码。这可确保在解密vault加密文件时先选择正确的密码,这比强制Ansible尝试用户提供的所有vault密码直至找到正确的密码要快。

3.管理事实

3.1描述ansible事实

Ansible事实是Ansible在受管主机上自动检测到的变量。事实中包含有与主机相关的信息,可以像play中的常规变量、条件、循环或依赖于从受管主机收集的值的任何其他语句那样使用。借助事实,可以方便地检索受管主机的状态,并根据该状态确定要执行的操作。
通常,每个play在执行第一个任务之前会先自动运行setup模块来收集事实。查看为受管主机收集的事实的一种方式是,运行一个收集事实并使用debug模块(debug用来打印事实到终端)显示ansible_facts变量值的简短playbook:

[root@king playbook]# vim 123.yml 
---
- hosts: all
  tasks:
    - name: 获取事实
      debug:
        var: ansible_facts

[root@king playbook]# ansible-playbook 123.yml   //打印受管主机上所有的事实到终端上

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

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

TASK [获取事实] **********************************************************************************
ok: [192.168.120.130] => {
    "ansible_facts": {
        "all_ipv4_addresses": [
            "192.168.120.130"
            .......
          "date_time": {
            .........
      "virtualization_role": "guest",
        "virtualization_type": "VMware"
    }
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@king playbook]# vim 123.yml 
---
- hosts: all
  tasks:
    - name: 获取事实
      debug:
        var: ansible_facts ['date_time']       //打印出任务中的日历时间任务事实
[root@king playbook]# ansible-playbook 123.yml 

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

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

TASK [获取事实] **********************************************************************************
ok: [192.168.120.130] => {
    "ansible_facts [\"date_time\"]": {
        "date": "2021-11-04",
        "day": "04",
        "epoch": "1635999555",
        "hour": "12",
        "iso8601": "2021-11-04T04:19:15Z",
        "iso8601_basic": "20211104T121915846382",
        "iso8601_basic_short": "20211104T121915",
        "iso8601_micro": "2021-11-04T04:19:15.846382Z",
        "minute": "19",
        "month": "11",
        "second": "15",
        "time": "12:19:15",
        "tz": "CST",
        "tz_offset": "+0800",
        "weekday": "Thursday",
        "weekday_number": "4",
        "weeknumber": "44",
        "year": "2021"
    }
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

如果变量的值为散列/字典类型,则可使用两种语法来获取其值 。比如:

ansible_facts['default_ipv4']['date_time']也可以写成ansible_facts.default_ipv4.date_time

3.2ansible事实作为变量注入

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

许多较旧的playbook仍然使用作为变量注入的事实,而不是在ansible_facts变量下创建命名空间的新语法。我们可以使用临时命令来运行setup模块,以此形式显示所有事实的值。以下示例中当受控主机很少时,使用一个临时命令在受管主机上192.168.120.130运行setup模块(就可以看到所有获取到事实):

[root@king playbook]# ansible all -m setup
192.168.120.130 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.120.130"
        ],
........
  ],
        "module_setup": true
    },
    "changed": false
}

Ansible事实名称比较:

ansible_facts新版本形式旧事实变量形式
ansible_facts[‘hostname’]ansible_hostname
ansible_facts[‘dns’][‘nameservers’]ansible_dns[‘nameservers’]
...ansible_facts新版形式:
[root@king playbook]# vim 123.yml
---
- hosts: all
  tasks:
    - name: 获取事实
      debug:
        var: ansible_facts ['dns']['nameservers']
[root@king playbook]# ansible-playbook 123.yml 

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

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

TASK [获取事实] **********************************************************************************
ok: [192.168.120.130] => {
    "ansible_facts ['dns']['nameservers']": [
        "114.114.114.114"
    ]
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

...ansible_ 旧版本形式(一样通用)[root@king playbook]# vim 123.yml 

---
- hosts: all
  tasks:
    - name: 获取事实
      debug:
        var: ansible_dns ['nameservers']
[root@king playbook]# ansible-playbook 123.yml 

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

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

TASK [获取事实] **********************************************************************************
ok: [192.168.120.130] => {
    "ansible_dns ['nameservers']": [
        "114.114.114.114"
    ]
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@king playbook]# vim 123.yml 

---
- hosts: all
  tasks:
    - name: 获取事实
      debug:
        var: ansible_hostname
[root@king playbook]# ansible-playbook 123.yml 

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

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

TASK [获取事实] **********************************************************************************
ok: [192.168.120.130] => {
    "ansible_hostname": "CAT"
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

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

[root@king~]# vim /etc/ansible/ansible.cfg
inject_facts_as_vars = True 👉False //就可以关闭事实旧命名系统用法

inject_facts_as_vars的默认值在Ansible的未来版本中可能会更改为False。如果设置为False,则只能使用新的ansible_facts.*命名系统引用Ansible事实。所以建议大家一开始就要适应这种方式。

3.3关闭事实收集

有时我们不想为play收集事实。这样做的原因可能有:
①不准备使用任何事实
②希望加快play速度
③希望减小play在受管主机上造成的负载
④受管主机因为某种原因无法运行setup模块
⑤需要安装一些必备软件后再收集事实

以上种种原因导致我们可能想要永久或暂时关闭事实收集的功能,要为play禁用事实收集功能,可将gather_facts关键字设置为no:

[root@king playbook]# vim 123.yml 

---
- hosts: all
  gather_facts: no
  tasks:
    - name: get facts
      debug:
        var: ansible_facts ['all_ipv4_addresses']
[root@king playbook]# ansible-playbook 123.yml 

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

TASK [get facts] *****************************************************************************
ok: [192.168.120.130] => {
    "ansible_facts ['all_ipv4_addresses']": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

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

[root@king playbook]# vim 123.yml 

---
- hosts: all
  gather_facts: no
  tasks:
    - name: get facts
      setup:
    - name: print
      debug:
        var: ansible_facts ['all_ipv4_addresses']
[root@king playbook]# ansible-playbook 123.yml 

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

TASK [get facts] *****************************************************************************
ok: [192.168.120.130]

TASK [print] *********************************************************************************
ok: [192.168.120.130] => {
    "ansible_facts ['all_ipv4_addresses']": [
        "192.168.120.130"
    ]
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.4创建自定义事实

除了使用系统捕获的事实外,我们还可以自定义事实,并将其本地存储在每个受管主机上。这些事实整合到setup模块在受管主机上运行时收集的标准事实列表中。它们让受管主机能够向Ansible提供任意变量,以用于调整play的行为。
自定义事实可以在静态文件中定义,格式可为INI文件或采用JSON。它们也可以是生成JSON输出的可执行脚本,如同动态清单脚本一样。
有了自定义事实,我们可以为受管主机定义特定的值,供play用于填充配置文件或有条件地运行任务。动态自定义事实允许在play运行时以编程方式确定这些事实的值,甚至还可以确定提供哪些事实。

默认情况下,setup模块从各受管主机的**/etc/ansible/facts.d目录下(该目录需手动创建)的文件和脚本中加载自定义事实。各个文件或脚本的名称必须以.fact**结尾才能被使用。动态自定义事实脚本必须输出JSON格式的事实,而且必须是可执行文件。
以下是采用INI格式编写的静态自定义事实文件。INI格式的自定义事实文件包含由一个部分定义的顶层值,后跟用于待定义的事实的键值对:

在受控主机上:
[root@CAT ~]# cd /etc/
[root@CAT etc]# mkdir -p ansible/facts.d
[root@CAT etc]# cd ansible/facts.d/
[root@CAT facts.d]# vim sss.fact

[packages]
web_package = httpd
db_package = mariadb-server

[users]
user1 = joe
user2 = jane


↓可以利用临时命令在受管主机上运行setup模块来检查自定义事实的结构。
在控制主机上:
[root@king ~]# ansible all -m setup
.......
"ansible_local": {
            "sss": {
                "packages": {
                    "db_package": "mariadb-server",
                    "web_package": "httpd"
                },
                "users": {
                    "user1": "joe",
                    "user2": "jane"
                }
            }
......

自定义事实文件不能采用playbook那样的YAML格式。JSON格式是最为接近的等效格式。

自定义事实由setup模块存储在ansible_facts.ansible_local变量中。
事实按照定义它们的文件的名称来整理。例如,假设前面的自定义事实由受管主机上保存为/etc/ansible/facts.d/custom.fact的文件生成。在这种情况下,ansible_facts.ansible_local[‘custom’][‘users’][‘user1’]的值为joe。

[root@king playbook]# vim 123.yml 

---
- hosts: all
  gather_facts: no
  tasks:
    - name: get facts
      setup:
    - name: print package_httpd
      debug:
        var: ansible_facts.ansible_local ['sss']['packages']['web_package']
[root@king playbook]# ansible-playbook 123.yml 

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

TASK [get facts] *****************************************************************************
ok: [192.168.120.130]

TASK [print package_httpd] *******************************************************************
ok: [192.168.120.130] => {
    "ansible_facts.ansible_local ['sss']['packages']['web_package']": "httpd"
}

PLAY RECAP ***********************************************************************************
192.168.120.130            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.5魔法变量使用

一些变量并非事实或通过setup模块配置,但也由Ansible自动设置。这些魔法变量也可用于获取与特定受管主机相关的信息。

最常用的魔法变量有四个:

  • hostvars:包含受管主机的变量,可以用于获取另一台受管主机的变量的值。
    如果还没有为受管主机收集事实,则它不会包含该主机的事实
  • group_names:列出当前受管主机所属的所有组
  • groups:列出清单中的所有组和主机
  • inventory_hostname:包含清单中配置的当前受管主机的主机名称。因为各种原因有可能与事实报告的主机名称不同

此外还有其它魔法变量,可查看官网选择special_variables:
ansible官网链接点击

使用debug模块报告特定主机的变量的内容:

[root@king playbook]# ansible all -m debug -a 'var=hostvars["localhost"]'
192.168.120.130 | SUCCESS => {
    "hostvars[\"localhost\"]": {
        "ansible_check_mode": false,
        "ansible_connection": "local",
        "ansible_diff_mode": false,
        "ansible_facts": {},
        "ansible_forks": 5,
        "ansible_inventory_sources": [
            "/etc/ansible/file"
.....
[root@king playbook]# ansible all -m debug -a 'var=ansible_diff_mode'
192.168.120.130 | SUCCESS => {
    "ansible_diff_mode": false
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值