管理变量、机密和事实

1. 管理变量

1.1 Ansible变量简介

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

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

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

1.1.1 命名变量

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

1.1.2 定义变量

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

  • 全局范围:从命令行或Ansible配置设置的变量
  • Play范围:在play和相关结构中设置的变量
  • 主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量

1.2 在Playbook中定义变量

示例:现在用变量给受控机安装阿帕奇

1.查看受控机没有阿帕奇

[root@localhost ~]# rpm -qa|grep httpd
[root@localhost ~]# rpm -qa|grep httpd
  1. 在主控机playbook中编写
[root@localhost playbook]# vim myplay.yml 

---
- hosts: 192.168.50.136
  vars:
    package_name: httpd
  tasks:
    - name: jjyy
      yum:
        name: '{{ package_name }}'
        state: present

  1. 运行playbook
[root@localhost playbook]# ansible-playbook  myplay.yml 

PLAY [192.168.50.136] **********************************************************

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

TASK [jjyy] ********************************************************************
ok: [192.168.50.136]

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

  1. 查看受控机是否安装了阿帕奇(完成安装)
[root@localhost ~]# rpm -qa|grep httpd
httpd-filesystem-2.4.37-21.module_el8.2.0+382+15b0afa8.noarch
httpd-2.4.37-21.module_el8.2.0+382+15b0afa8.x86_64
httpd-tools-2.4.37-21.module_el8.2.0+382+15b0afa8.x86_64
centos-logos-httpd-80.5-2.el8.noarch

示例:把变量写到vars文件里去卸载受控机的阿帕奇
1 . 在playbook下面创建一个vars目录,该目录必须和myplay.yml是同级目录

[root@localhost playbook]# mkdir vars
[root@localhost playbook]# ls
myplay.yml  vars

2 . 进入vars编写一个(叫测试的文件)test.yml的文件

[root@localhost playbook]# cd vars
[root@localhost vars]# vim test.yml

packages_name: httpd
~                                      

3 . 使用tree查看test.yml在哪个文件下面

[root@localhost playbook]# tree vars
vars
└── test.yml

0 directories, 1 file

4 . 进入myplay.yml,把vars改成vars_files并跟上文件,把下面的package加个s

[root@localhost playbook]# vim myplay.yml 

---
- hosts: 192.168.50.136
  vars_files:
    - vars/test.yml
  tasks:
    - name: jjyy
      yum:
        name: '{{ packages_name }}'
        state: absent                           absent : 卸载(因为我要卸载阿帕奇所以用absent)

5 . 执行playbook

[root@localhost playbook]# ansible-playbook  myplay.yml 


PLAY [192.168.50.136] **********************************************************

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

TASK [jjyy] ********************************************************************
ok: [192.168.50.136]

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


6 . 查看受控机是否已经卸载阿帕奇(已卸载)

[root@localhost ~]# rpm -qa|grep httpd
httpd-filesystem-2.4.37-21.module_el8.2.0+382+15b0afa8.noarch
httpd-tools-2.4.37-21.module_el8.2.0+382+15b0afa8.x86_64
centos-logos-httpd-80.5-2.el8.noarch

1.3 主机变量和组变量

创建group_vars和host_vars两个目录。这两个目录分别包含用于定义组变量和主机变量的文件。

[root@localhost ~]# tree /opt/qq
/opt/qq
├── files                                           放文件
├── group_vars                                      主机组对应的变量
├── hosts_vars                                      主机对应的变量
├── inventory                                       项目里面有哪些主机就在此写哪些主机
└── playbook.yml                                    编写playbook

3 directories, 2 files

比如:进入qq下面的inventory进行编写也可以ping通受控机

[root@localhost qq]# vim inventory 

192.168.50.136 ansible_password=redhat


[root@localhost qq]# ansible 192.168.50.136 -i inventory -m ping
192.168.50.136 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

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

[root@localhost qq]# vim playbook.yml 

---
- hosts: all
  tasks:
    - name: install httpd and print result
      yum:
        name: httpd
        state: present
      register: result                                              register捕获命令输出
    - debug: var=result                                         debug模块可以打印一个变量(这里就打印result变量)
~                                            

[root@localhost qq]# ansible-playbook  playbook.yml 

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

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

TASK [install httpd and print result] ******************************************
changed: [192.168.50.136]

TASK [debug] *******************************************************************
ok: [192.168.50.136] => {
    "result": {
        "changed": true,
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "Installed: httpd-2.4.37-21.module_el8.2.0+382+15b0afa8.x86_64",
            "Installed: mod_http2-1.11.3-3.module_el8.2.0+307+4d18d695.x86_64"
        ]
    }
}

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

2. 管理机密

2.1 创建加密文件

  1. 创建时需要输入密码
[root@localhost group_vars]# ansible-vault create webservers             ansible-vault create +文件名  来创建加密文件
New Vault password:                                                                              输入密码123456
Confirm New Vault password: 
[root@localhost group_vars]# ls
webservers
  1. 创建时不需要输入密码
  • 先在vault密码文件里写入密码12345 , 该文件不要让别人知道
[root@localhost group_vars]# vim vault_pass

123456
  • 用以下命令来创建一个加密文件
[root@localhost group_vars]# ansible-vault create --vault-password-file=vault_pass webservers
[root@localhost group_vars]# ls
vault_pass  webservers

2.2 查看加密文件

[root@localhost group_vars]# ansible-vault view webservers           使用view来查看加密文件,需要输入密码
Vault password: 
ansible_password: redhat

2.3 编辑现有的加密文件

[root@localhost group_vars]# ansible-vault edit webservers                      使用edit来编辑加密文件
Vault password:                                                                 输入密码后编写name: tom
[root@localhost group_vars]# ansible-vault view webservers  
Vault password: 
ansible_password: redhat                                                        view查看该文件就有刚编写的name: tom
name: tom     

2.4 加密已存在的文件

[root@localhost group_vars]# vim webservers                                              先写一个有内容的文件
[root@localhost group_vars]# cat webservers                                              未加密可以查看其内容
ansible_password: redhat
[root@localhost group_vars]# ansible-vault encrypt webservers                            用encrypt对该文件加密
New Vault password: 
Confirm New Vault password: 
Encryption successful                                                                    加密成功
[root@localhost group_vars]# cat webservers                                              用cat命令查看不了加密文件
$ANSIBLE_VAULT;1.1;AES256
32306438396564386139376336653134663137666565623332646135663834326363343132383737
3039343663366130323932353730383136393839616232360a326332373336303836663762653063
32376632636232393239666137393863386238323164373230386466613466313863613466663664
3364643236323336660a636361663835386166386364633662623631343937643435613462333166
35376564333736363866386565306334396662313962383435623566323664636134
[root@localhost group_vars]# ansible-vault view webservers                               用view来查看加密文件
Vault password: 
ansible_password: redhat

2.5 解密已存在的文件

[root@localhost group_vars]# ansible-vault decrypt webservers                      用decrpt来解密文件
Vault password: 
Decryption successful                                                              解密成功
[root@localhost group_vars]# cat webservers                                        cat命令可以查看该文件
ansible_password: redhat
[root@localhost group_vars]# 

2.6 更改加密文件密码

[root@localhost group_vars]# ansible-vault rekey webservers                使用rekey来修改密码
Vault password:                                                            输入旧密码123456
New Vault password:                                                        输入新密码 maqiang
Confirm New Vault password: 
Rekey successful                                                           修改成功
[root@localhost group_vars]# ansible-vault view webservers                 使用新密码查看加密文件
Vault password: 
ansible_password: redhat

2.7 playbook和ansible vault

  • ping通主机需要给加密文件密码
[root@localhost qq]# ansible all -i inventory --vault-id @prompt -m ping
Vault password (default):                                                                   输入加密文件密码maqiang
192.168.50.136 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
[root@localhost qq]# ansible all -i inventory --vault-id 136@prompt -m ping                 加个136(主机名)可以ping哪台主机
Vault password (136): 
192.168.50.136 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

  • 运行playbook需要给加密文件密码才能运行
[root@localhost qq]# ansible-playbook -i inventory --vault-id @prompt playbook.yml 
Vault password (default): 

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

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

TASK [install httpd and print result] ******************************************
ok: [192.168.50.136]

TASK [debug] *******************************************************************
ok: [192.168.50.136] => {
    "result": {
        "changed": false,
        "failed": false,
        "msg": "Nothing to do",
        "rc": 0,
        "results": []
    }
}

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

[root@localhost qq]# 

2.8 变量文件管理的推荐做法

[root@localhost qq]# ls
files       hosts_vars  playbook.yml
group_vars  inventory
[root@localhost qq]# cd group_vars/
[root@localhost group_vars]# mkdir webservers                        创建一个webservers的目录
[root@localhost group_vars]# cd webservers/                          进入该目录
[root@localhost webservers]# ls
[root@localhost webservers]# vim var                                 不用加密的东西放入var中
[root@localhost webservers]# ansible-vault create vault              需要加密的东西放入vault中
New Vault password: 
Confirm New Vault password: 
[root@localhost webservers]# cd ../..
[root@localhost qq]# ls
files       hosts_vars  playbook.yml
group_vars  inventory
[root@localhost qq]# tree .
.
├── files
├── group_vars
│   └── webservers                 一个目录
│       ├── var                    放不用加密的文件
│       └── vault                  放需要加密的文件
├── hosts_vars
├── inventory
└── playbook.yml

4 directories, 4 files
[root@localhost qq]# ansible all -i inventory --vault-id @prompt -m ping
Vault password (default): 
192.168.50.136 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

3. 管理事实

3.1 使用debug模块查看事实

[root@localhost qq]# vim playbook.yml                    

---
- hosts: all
  tasks:
    - name: 取出所有事实
      debug:
          var: ansible_facts

[root@localhost qq]# ansible-playbook  --syntax-check playbook.yml                           查看语法是否错误

playbook: playbook.yml
[root@localhost qq]# ansible-playbook --vault-id @prompt playbook.yml 
Vault password (default): 

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

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

TASK [取出所有事实] ******************************************************************                          取出所有事实
ok: [192.168.50.136] => {
    "ansible_facts": {
        "all_ipv4_addresses": [
            "192.168.50.136"
        ],
        "all_ipv6_addresses": [
   
   ......
   
       "system_capabilities_enforced": "True",
        "system_vendor": "VMware, Inc.",
        "uptime_seconds": 20458,
        "user_dir": "/root",
        "user_gecos": "root",
        "user_gid": 0,
        "user_id": "root",
        "user_shell": "/bin/bash",
        "user_uid": 0,
        "userspace_architecture": "x86_64",
        "userspace_bits": "64",
        "virtualization_role": "guest",
        "virtualization_type": "VMware"
    }
}

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

  • Ansible事实的示例

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

  • 比如查看IPV4地址
[root@localhost qq]# vim playbook.yml 

---
- hosts: all
  tasks:
    - name: 取出所有事实
      debug:
          var: ansible_facts['default_ipv4']['address']      
[root@localhost qq]# ansible-playbook --vault-id @prompt playbook.yml 
Vault password (default): 

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

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

TASK [取出所有事实] ******************************************************************
ok: [192.168.50.136] => {
    "ansible_facts['default_ipv4']['address']": "192.168.50.136"
}                                    取出IP

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

  • 比如查看主机地址
[root@localhost qq]# vim playbook.yml 

---
- hosts: all
  tasks:
    - name: 取出所有事实
      shell: echo 本机的IP地址是:{{ ansible_facts['default_ipv4']['address']  }}                 也可以用点的方式取出事实  {{ ansible_facts.default_ipv4.address  }}

      register: result                                                                                      打印结果
    - debug: var=result                     
[root@localhost qq]# ansible-playbook --vault-id @prompt playbook.yml 
Vault password (default): 

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

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

TASK [取出所有事实] ******************************************************************
changed: [192.168.50.136]

TASK [debug] *******************************************************************
ok: [192.168.50.136] => {
    "result": {
        "changed": true,
        "cmd": "echo 本机的IP地址是:192.168.50.136",
        "delta": "0:00:00.003446",
        "end": "2020-09-06 15:14:19.278589",
        "failed": false,
        "rc": 0,
        "start": "2020-09-06 15:14:19.275143",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "本机的IP地址是:192.168.50.136",
        "stdout_lines": [
            "本机的IP地址是:192.168.50.136"
        ]
    }
}

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

3.2 Ansible事实作为变量注入

选定的Ansible事实名称比较

ansible_facts形式旧事实变量形式
ansible_facts[‘hostname’]ansible_hostname
ansible_facts[‘fqdn’]ansible_fqdn
ansible_facts[‘default_ipv4’][‘address’]ansible_default_ipv4[‘address’]
ansible_facts[‘interfaces’]ansible_interfaces
ansible_facts[‘devices’][‘vda’][‘partitions’][‘vda1’][‘size’]ansible_devices[‘vda’][‘partitions’][‘vda1’][‘size’]
ansible_facts[‘dns’][‘nameservers’]ansible_dns[‘nameservers’]
ansible_facts[‘kernel’]ansible_kernel
  • 示例:
用新的写法
[root@localhost playbook]# vim myplay.yml 

---
- hosts: all
  tasks:
    - name: jfldajlfd
      debug:
        msg: >
          {{ ansible_facts['hostname'] }}                           

[root@localhost playbook]# ansible-playbook -C myplay.yml 

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

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

TASK [jfldajlfd] ***************************************************************
ok: [192.168.50.136] => {
    "msg": "localhost      \n"
}

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



用旧的写法
[root@localhost playbook]# vim myplay.yml 

---
- hosts: all
  tasks:
    - name: jfldajlfd
      debug:
        msg: >
          {{ ansible_hostname }}

[root@localhost playbook]# ansible-playbook -C myplay.yml 

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

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

TASK [jfldajlfd] ***************************************************************
ok: [192.168.50.136] => {
    "msg": "localhost      \n"
}

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

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

# inject_facts_as_vars = True           将注释取消,把Ture改为False后将不能使用旧的写法

3.3 关闭事实收集

  • 禁用play事实收集功能,可将gather_facts关键字设置为no:
[root@localhost playbook]# vim myplay.yml 

---
- hosts: all
  gather_facts: no                            添加此行将无法进行收集事实
  tasks:
    - name: jfldajlfd
      debug:
        msg: >
          {{ ansible_facts['hostname'] }}

[root@localhost playbook]# ansible-playbook -C myplay.yml 

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

TASK [jfldajlfd] ***************************************************************
fatal: [192.168.50.136]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'hostname'\n\nThe error appears to be in '/root/playbook/myplay.yml': line 5, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: jfldajlfd\n      ^ here\n"}                                          报错,无法收集事实

PLAY RECAP *********************************************************************
192.168.50.136             : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
  • 使用setup模块临时开启事实收集
[root@localhost playbook]# vim myplay.yml 

---
- hosts: all
  gather_facts: no
  tasks:
    - name: jjyy
      setup:                             添加setup模块
    - name: jfldajlfd
      debug:
        msg: >
          {{ ansible_facts['hostname'] }}
[root@localhost playbook]# ansible-playbook -C myplay.yml 

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

TASK [jjyy] ********************************************************************
ok: [192.168.50.136]

TASK [jfldajlfd] ***************************************************************
ok: [192.168.50.136] => {
    "msg": "localhost      \n"
}

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

3.4 创建自定义事实

  1. 在受控机上采用INI格式编写的静态自定义事实文件
[root@localhost facts.d]# vi jjyy.fact

[packages]
web_package = httpd
db_package = mariadb-server

[users]
user1 = joe
user2 = jane
  1. 在主控机上搜索jjyy
[root@localhost ansible]# ansible all -m setup|less

......
           "jjyy": {
                "packages": {
                    "db_package": "mariadb-server",
                    "web_package": "httpd"
......

3.5 使用魔法变量

最常用的有四个:

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

示例:

[root@localhost ansible]# ansible all -m debug -a 'var=hostvars'                  用debug模块查看受管主机的变量
192.168.50.136 | SUCCESS => {
    "hostvars": {
        "192.168.50.136": {
            "ansible_check_mode": false,
            "ansible_diff_mode": false,
            "ansible_facts": {},
            "ansible_forks": 5,
            "ansible_inventory_sources": [
                "/etc/ansible/inventory"
            ],
            "ansible_password": "redhat",
            "ansible_playbook_python": "/usr/bin/python3.6",
            "ansible_verbosity": 0,
            "ansible_version": {
                "full": "2.9.11",
                "major": 2,
                "minor": 9,
                "revision": 11,
                "string": "2.9.11"
            },
            "group_names": [
                "ungrouped"
            ],
            "groups": {
                "all": [
                    "192.168.50.136"
                ],
                "ungrouped": [
                    "192.168.50.136"
                ]
            },
            "inventory_dir": "/etc/ansible",
            "inventory_file": "/etc/ansible/inventory",
            "inventory_hostname": "192.168.50.136",
            "inventory_hostname_short": "192",
            "omit": "__omit_place_holder__c4523dfb5de86623c8328d7a9e4d91434f7fb22b",
            "playbook_dir": "/etc/ansible"
        }
    }
}

[root@localhost ansible]# ansible all -m debug -a "var=hostvars['192.168.50.136']['ansible_password']"   查看上面的redhat
192.168.50.136 | SUCCESS => {
    "hostvars['192.168.50.136']['ansible_password']": "redhat"
}

[root@localhost ansible]# ansible all -m debug -a 'var=groups'
192.168.50.136 | SUCCESS => {
    "groups": {
        "all": [
            "192.168.50.136"
        ],
        "ungrouped": [
            "192.168.50.136"
        ]
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百慕卿君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值