ansible管理变量和加解密

ansible管理变量和加解密

ansible变量简介

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

例如,变量可能包含下面这些值:

  • 要创建的用户

  • 要安装的软件包

  • 要重新启动的服务

  • 要删除的文件

  • 要从互联网检索的存档

命名变量规则

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

无效的变量 有效的变量
qqq 123 qqq_123
list 123 abc list_123_abc
QQQ.123 QQQ_123
list @1 list1 或 list_1

定义变量

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

​ 全局变量:从命令行或Ansible配置设置的变量

​ Play范围:在play和相关结构中设置的变量

​ 主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量

如果在多个xekl(级别)定义了相同名称的变量,则采用优先级别最高的变量。窄范围优先于更广泛的范围:由清单定义的变量将被playbook定义的变量覆盖,后者将被命令行中定义的变量覆盖。

playbook中的变量

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

在playbook中定义变量

编写playbook时,可以定义自己的变量,然后在任务中调用这些值。

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

---
- hosts: server1
  remote_user: tom
  vars:                              //变量模块
    IP: 192.168.56.199              //定义变量
    NAME: node4
  tasks:
    - name: test
      lineinfile:
        path: /etc/hosts
        line: "{{ IP  }} {{ NAME  }}"   //如果{{ IP }}前面有字母就不用打""
        state: present


//查看结果
[root@server1 etc]# cat  hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.130 server1
192.168.56.199 node4

也可以在playbook外部定义变量

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

//编写变量文件

[root@control book]# ls
ansible.cfg  node1.yml  playbook  vars
[root@control book]#  cat  vars/time.yml 
IP: 192.168.56.179
NAME: node7

//变量文件必须和清单文件在同一个级别,不然无法找到变量文件

[root@control vars]# tree  /opt/book/vars/
/opt/book/vars/
├── ansible.cfg
├── host_vars
│   ├── 192.168.56.130
│   ├── node1.yml
│   └── time.yml
└── playbook

//修改文件

[root@control vars]# cat  node1.yml 
---
- hosts: server1
  remote_user: tom
  vars_files:           //局外变量模块
    - vars/time.yml     //变量地址
  tasks:
    - name: test
      lineinfile:
        path: /etc/hosts
        line: "{{ IP  }} {{ NAME  }}"   //引用变量
        state: present

//执行
[root@control vars]# ansible-playbook node1.yml 

PLAY [server1] *****************************************************************

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

TASK [test] ********************************************************************
changed: [192.168.56.130]

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


//查看
[root@server1 etc]# cat  hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.130 server1
192.168.56.199 node4
192.168.56.179 node7

主机变量和组变量

直接应用于主机的清单变量分为两在类:

  • 主机变量,应用于特定主机
  • 组管理,应用于一个主机组或一组主机组中的所有主机

主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高

playbook里的变量>主机变量>组变量

若要定义主机变量和组变量,一种方法是直接在清单文件中定义。

这是较旧的做法,不建议采用,但你可能会在未来的工作当中遇到。

定义主机变量:

[root@control vars]# cat  playbook 
[server1]
192.168.56.130   ansible_user=root  ansible_password=1

使用目录填充主机和组变量

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

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

创建主机目录

[root@control vars]# tree  /opt/book/vars/
/opt/book/vars/
├── ansible.cfg
├── host_vars
│   ├── 192.168.56.131
│   ├── node1.yml
│   └── time.yml
└── playbook

//写入主机目录文件
[root@control vars]# cat  host_vars/192.168.56.131 
ansibel_user: root
ansible_password: 1

//查看清单文件
[root@control vars]# cat  playbook 
[server1]
192.168.56.131 


//测试
[root@control vars]# ansible all -m ping
192.168.56.131 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}


//定义主机变量
[root@control vars]# cat  host_vars/192.168.56.131 
ansibel_user: root
ansible_password: 1
IP: 192.168.56.199
NAME: www


//执行
[root@control vars]# cat  host_vars/node1.yml 
---
- hosts: '192.168.56.131'
  tasks:
    - name: test
      lineinfile:
         path: /etc/hosts
         line: "{{ IP  }} {{ NAME }}"
         state: present

//查看结果
[root@localhost ~]# cat   /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.199 www

如果局内和局外变量相同以局内变量为准

[root@control vars]# cat  host_vars/192.168.56.131 
ansibel_user: root
ansible_password: 1
IP: 192.168.56.110        //定义局外变量
NAME: QQQ

[root@control vars]# cat  host_vars/node1.yml 
---
- hosts: '192.168.56.131'
  gather_facts: no
  vars:          
    IP: 192.168.56.188      //定义局内变量
    NAME: LLL
  tasks:
    - name: test
      lineinfile:
         path: /etc/hosts
         line: "{{ IP  }} {{ NAME }}"
         state: present
//执行
[root@control vars]# ansible-playbook host_vars/node1.yml 

PLAY [192.168.56.131] **********************************************************

TASK [test] ********************************************************************
changed: [192.168.56.131]

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


//查看结果
[root@localhost ~]# cat   /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.199 www
192.168.56.188 LLL       //只添加了局内变量


使用数组作为变量

除了将同一元素相关的配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,也可以使用数组。这种做法的一个好处在于,数组是可以浏览的

创建组:

[root@control vars]# cat   host_vars/192.168.56.131  
ansibel_user: root
ansible_password: 1

info:
  node2:
    ip: 5.5.5.5
    max: www.aliyun.com
  node3:
    ip: 6.6.6.6
    min: www.baidu.com


[root@control vars]# cat  host_vars/node1.yml 
---
- hosts: '192.168.56.131'
  gather_facts: no
  vars:
    IP: 192.168.56.188
    NAME: LLL
  tasks:
    - name: test
      lineinfile:
         path: /etc/hosts
         line: "{{ info.node2.ip }} {{ info.node3.min  }}"
         state: present


"{{info.node2.ip}} {{info.node3.min}}"


//查看结果
[root@localhost ~]# cat   /etc/hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
5.5.5.5 www.baidu.com

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

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

标准输入:STDIN

标准输出:STDOUT

标准错误:STDERR

以下playbook演示了如何为调试用途捕获命令输出:

[root@control vars]# cat  host_vars/node1.yml ---
- hosts: '192.168.56.131'
  gather_facts: no
  tasks:
    - name: test
      command: "echo hello time"   //输出结果
      register: result      //注册名字

    - debug: var=result     //

[root@control vars]# ansible-playbook host_vars/node1.yml  

PLAY [192.168.56.131] **********************************************************

TASK [test] ********************************************************************
changed: [192.168.56.131]

TASK [debug] *******************************************************************
ok: [192.168.56.131] => {
    "result": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/libexec/platform-python"
        },
        "changed": true,
        "cmd": [
            "echo",
            "hello",
            "time"
        ],
        "delta": "0:00:00.001394",
        "end": "2021-07-22 23:01:09.288632",
        "failed": false,
        "rc": 0,
        "start": "2021-07-22 23:01:09.287238",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "hello time",
        "stdout_lines": [
            "hello time"     //捕获
        ]
    }
}

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

//捕获打印输出结果

[root@control vars]# cat  host_vars/node1.yml ---
- hosts: '192.168.56.131'
  gather_facts: no
  tasks:
    - name: test
      command: "echo hello time"
      register: result

    - name: create 
      shell: "echo {{ result['stdout'] }} > /opt/abc"
//受控主机上必须有/opt/abc这个文件

[root@control vars]# ansible-playbook host_vars/node1.yml  

//执行
PLAY [192.168.56.131] **********************************************************

TASK [test] ********************************************************************
changed: [192.168.56.131]

TASK [create] ******************************************************************
changed: [192.168.56.131]

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


//查看结果
[root@localhost opt]# cat  abc 
hello time


管理机密

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

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

创建加密文件:

//创建加密文件
[root@control vars]# ansible-vault create took.ymlNew Vault password: 
Confirm New Vault password: 
[root@control vars]# ls
ansible.cfg  host_vars  took.yml
group_vars   playbook

//查看
[root@control group_vars]# ls
took.yml  //加密文件
[root@control group_vars]# cat  took.yml 
$ANSIBLE_VAULT;1.1;AES256
35313330376339343338366131383335623366396631663436383238646266383136353062356230
3437373338633230643133666563346463616265326566340a353336633934633939313835333338
36363034306364383236366434306537623635613565336562626235643566323735346166613537
3932623638393866620a396434663538663635373235353634386165623836386434323532653065
3339

查看加密的文件

[root@control group_vars]# ansible-vault view took.yml 
Vault password:    //输入密码查看
123

[root@control group_vars]# ls  -a
.  ..  .passwd  took.yml

[root@control group_vars]# cat .passwd //创建一个密码文件
123456


//用密码文件创建加密文件
[root@control vars]# ansible-vault create  --vault-password-file=group_vars/.passwd group_vars/pook.yml
[root@control vars]# ansible-vault view group_vars/pook.yml 

//输入密码查看
[root@control vars]# ansible-vault view group_vars/pook.yml 
Vault password: 
port: 9090

//用密码文件查看加密文件
[root@control vars]# ansible-vault view --vault-password-file=group_vars/.passwd  group_vars/pook.yml 
port: 9090

加密现有文件

[root@control vars]# ls
ansible.cfg  group_vars  host_vars  playbook

[root@control vars]# ansible-vault encrypt --vault-password-file=group_vars/.passwd playbook 
Encryption successful
//密码加密playbook文件

[root@control vars]# cat  playbook 
$ANSIBLE_VAULT;1.1;AES256
35336637323031346432353466306636366137303233356530653339353435663638313932313730
3032346163636538613633326661323836623638626530370a323163303266623265306631653838
35393034386139326234336661626638373166323461653063393435366435363837656231323630
3766386334663761640a353733633136343761383830356636323836663035333463653738343466
64316638623238663932356365346431623530343234313462373431303031366466

//用密码查看加密文件
[root@control vars]# ansible-vault view --vault-password-file=group_vars/.passwd playbook 
[server1]
192.168.56.131  


解密现有文件

[root@control vars]# ansible-vault decrypt --vault-password-file=group_vars/.passwd playbook //playbook加密文件 
Decryption successful
[root@control vars]# cat  playbook 
[server1]
192.168.56.131  

更改加密文件的密码

[root@control group_vars]# ls
pook.yml  took.yml

//修改密码
[root@control group_vars]# ansible-vault rekey pook.yml 
Vault password: 
New Vault password: 
Confirm New Vault password: 
//必须知道密码才能修改新密码

//用新密码查看文件
[root@control group_vars]# ansible-vault view --vault-password-file=pk pook.yml 
port: 9090

上一篇:ansible核心工具:playbook剧本


下一篇:Ansible-playbook剧本