ansible变量

定义变量规则:由字母/数字/下划线组成,变量需要以字母开头,ansible内置的关键字不能作为变量名。

ansible中,可以将变量简化为三个范围Global范围(高):从命令行和ansible配置设置的变量play范围(中):在play和相关结构中设置的变量Host范围(低):inventory、facts或register的变量,在主机组和个别主机上设置的变量三个范围的变量优先级依次升高,如果变量重复定义,则以优先级高的为准

注册和定义变量的各种方式

ansible中定义变量的方式有很多种,大致有:

  1. 将模块的执⾏结果注册为变量;
  2. 直接定义字典类型的变量;
  3. role中⽂件内定义变量;
  4. 命令⾏传递变量;
  5. 借助with_items迭代将多个task的结果赋值给⼀个变量;
  6. inventory中的主机或主机组变量;
  7. 内置变量。

vars定义变量

---
- name: test
  hosts: node1
  vars:
    - aa: 11
    - bb: 22
    - cc:
        a1: c31
        a2: c32
  tasks:
    - name: create debug1
      debug:
        msg: "{{aa}}"
    - name: create debug2
      debug:
        msg: "{{bb}}"
- name: create debug3
      debug:
        msg: "{{cc.a1}}"
- name: create debug4
      debug:
        msg: "{{cc.a2}}"

Vars_files定义变量

---
- name: test1234
  hosts: node1
  vars_files: /etc/ansible/var.yml
  tasks:
    - name: debug1
      debug:
        msg: "{{aa}}"
    - name: debug2
      debug:
        msg: "{{bb}}"
    - name: debug3
      debug:
        msg: "{{cc.a1}}"
    - name: debug4
      debug:
        msg: "{{cc.a2}}"

register注册变量

使⽤register选项,可以将当前task的输出结果赋值给⼀个变量。

[root@server ansible]# cat test.yaml
---
- name: test a playbook
  hosts: node1
  tasks: 
    - name: shell
      shell: "cat /tmp/zz"
      register: zz
    - name: create debug
      debug:
        var: zz
[root@server ansible]# ansible-playbook test.yaml
PLAY [test a playbook] *********************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [shell] *******************************************************************
changed: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "zz": {
        "changed": true,
        "cmd": "cat /tmp/zz",
        "delta": "0:00:00.005195",
        "end": "2020-07-29 10:06:17.704232",
        "failed": false,
        "rc": 0,
        "start": "2020-07-29 10:06:17.699037",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "zz",
        "stdout_lines": [
            "zz"
        ]
    }
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@server ansible]# cat test.yaml
---
- name: test a playbook
  hosts: node1
  tasks: 
    - name: shell
      shell: "cat /tmp/zz"
      register: zz
    - name: create debug
      debug:
        msg: "{{ zz.rc }}"
[root@server ansible]# ansible-playbook test.yaml
PLAY [test a playbook] *********************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [shell] *******************************************************************
changed: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": "0"
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

   

set_fact定义变量

set_fact和register的功能很相似,也是将值赋值给变量。它更像shell中变量的赋值⽅式,可以将某个变量的值赋值给另⼀个变量,也可以将字符串赋值给变量

通过ansible node1 -m setup 可以查询node1主机所有的事实变量

[root@server ansible]# cat test.yaml
---
- name: test a playbook
  hosts: node1
  tasks: 
    - name: hostname
      debug: 
        msg: "{{ ansible_fqdn }}"
[root@server ansible]# ansible-playbook test.yaml
PLAY [test a playbook] *********************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [hostname] ****************************************************************
ok: [node1] => {
    "msg": "node1.example.com"
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Vim cy.yml
---
- name: abc
  hosts: node1
  tasks:
    - name: test
      debug:
        msg: the ipv4 address of {{ansible_nodename}} is {{ansible_ens160.ipv4.address}}
[root@server ansible]# ansible-playbook cy.yml
PLAY [abc] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [test] ********************************************************************
ok: [node1] => {
  "msg": "the ipv4 address of node1.example.com is 172.16.30.10"
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

通过命令传入变量

---
- name: test4
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: my name is {{name1}}
    - name: create debug2
      debug:
        msg: my name is {{name2}}
[root@server ansible]# ansible-playbook d.yml -e 'name1=tom name2=marry'
PLAY [test4] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
 "msg": "my name is tom"
}
TASK [create debug2] ***********************************************************
ok: [node1] => {
"msg": "my name is marry"
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

主机清单中的变量

Vim  /etc/ansible/hosts
node1
node2
[net]
node1
node2
[net:vars]
vars1= 'hello'
vars2= 'hi'
Vim /etc/ansible/e.yml
---
- name: test5
  hosts: node1
  tasks:
    - name: create debug1
      debug:
        msg: say {{vars1}}
    - name: create debug2
      debug:
        msg: say {{vars2}}
[root@server ansible]# ansible-playbook e.yml
PLAY [test5] *******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug1] ***********************************************************
ok: [node1] => {
"msg": "say hello"
}
TASK [create debug2] ***********************************************************
ok: [node1] => {
"msg": "say hi"
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

除了可以在主机清单里定义变量外,还可以在/etc/ansible目录下创建group_vars和host_vars目录下定义变量

例子:

Cd  /etc/ansible/
Mkdir  host_vars
Cd  host_vars
Vim  node1
Vars1: groupvars1
Vars2: groupvars2
Vim  node1.yml
Vars1: abc
Vars2: bcd
Cd  /etc/ansible/
Vim  b.yml
---
- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: my name is {{vars1}}
    - name: create debug2
      debug:
        msg: my name is {{vars2}}
~  
[root@server ansible]# ansible-playbook b.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": "my name is groupvars1"
}
TASK [create debug2] ***********************************************************
ok: [node1] => {
    "msg": "my name is groupvars2"
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
删除/etc/ansible/host_vars/node1  保留/etc/ansible/host_vars/node1.yml,再次执行playbook
[root@server ansible]# ansible-playbook b.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": "my name is abc"
}
TASK [create debug2] ***********************************************************
ok: [node1] => {
    "msg": "my name is bcd"
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

由此验证得知:在/etc/ansible/host_vars目录中,node1文件名以主机命名,还可以命名为node1.yml,如果node1与node1.yml同时存在,则node1的优先级更高

内置变量ansible_version

Vim a.yml
---
- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{ansible_version}}"
[root@server ansible]# ansible-playbook a.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
 "msg": {
        "full": "2.9.18",
        "major": 2,
        "minor": 9,
        "revision": 18,
        "string": "2.9.18"
    }
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

内置变量inventory_hostname

---
- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{inventory_hostname}}"
[root@server ansible]# ansible-playbook a.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
 "msg": "node1"
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

内置变量play_hosts

---
- name: test
  hosts: net
  tasks:
    - name: create debug
      debug:
        msg: "{{play_hosts}}"
[root@server ansible]# ansible-playbook a.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
ok: [node2]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": [
        "node1",
        "node2"
    ]
}
ok: [node2] => {
    "msg": [
        "node1",
        "node2"
    ]
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

内置变量groups

---
- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{groups}}"
[root@server ansible]# ansible-playbook a.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": {
        "all": [
            "node1",
            "node2"
        ],
        "net": [
            "node1",
            "node2"
        ],
        "ungrouped": []
    }
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

内置变量group_names

---
- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{group_names}}"
[root@server ansible]# ansible-playbook a.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": [
        "net"
    ]
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

内置变量inventory_dir

---
- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{inventory_dir}}"
[root@server ansible]# ansible-playbook a.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create debug] ************************************************************
ok: [node1] => {
    "msg": "/etc/ansible"
}
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

With_items叠加变量---可以给一个变量赋予多个值

Vim c.yml
- name: test
  hosts: node1
  tasks:
    - name: abc
      shell:
        cmd: echo "{{item}}"
      with_items:
        - haha
        - heihei
        - hehe
      register: hi_var
    - name: debug1
      debug:
        var: hi_var.results[0].stdout
    - name: debug2
      debug:
        var: hi_var.results[1].stdout
    - name: debug3
      debug:
        var: hi_var.results[2].stdout
[root@server ansible]# ansible-playbook c.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [abc] *********************************************************************
changed: [node1] => (item=haha)
changed: [node1] => (item=heihei)
changed: [node1] => (item=hehe)
TASK [debug1] ******************************************************************
ok: [node1] => {
    "hi_var.results[0].stdout": "haha"
}
TASK [debug2] ******************************************************************
ok: [node1] => {
    "hi_var.results[1].stdout": "heihei"
}
TASK [debug3] ******************************************************************
ok: [node1] => {
    "hi_var.results[2].stdout": "hehe"
}
PLAY RECAP *********************************************************************
node1                      : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Vim d.yml
    - name: abc
      shell:
        cmd: echo "{{item}}"
      with_items:
        - haha
        - heihei
        - hehe
      register: hi_var
    - name: debug1
      debug:
        msg: "{{hi_var}}"
[root@server ansible]# ansible-playbook d.yml
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [abc] *********************************************************************
changed: [node1] => (item=haha)
changed: [node1] => (item=heihei)
changed: [node1] => (item=hehe)
TASK [debug1] ******************************************************************
ok: [node1] => {
    "msg": {
        "changed": true,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo \"haha\"",
                "delta": "0:00:00.003206",
                "end": "2021-04-09 00:36:52.433624",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo \"haha\"",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "haha",
                "rc": 0,
                "start": "2021-04-09 00:36:52.430418",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "haha",
                "stdout_lines": [
                    "haha"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo \"heihei\"",
                "delta": "0:00:00.002276",
                "end": "2021-04-09 00:36:52.676159",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo \"heihei\"",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "heihei",
                "rc": 0,
                "start": "2021-04-09 00:36:52.673883",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "heihei",
                "stdout_lines": [
                    "heihei"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo \"hehe\"",
                "delta": "0:00:00.002589",
                "end": "2021-04-09 00:36:52.920442",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo \"hehe\"",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "hehe",
                "rc": 0,
                "start": "2021-04-09 00:36:52.917853",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "hehe",
                "stdout_lines": [
                    "hehe"
                ]
            }
        ]
    }
}
PLAY RECAP *********************************************************************
node1                      : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

管理机密

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

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

创建加密的文件:

  要创建新的加密文件,使用ansible-vault create filename命令,默认使用vi编辑

ansible-vault  create  test.yml

输入密码:redhat

确认密码:redhat

---
- name: test1
  hosts: node1
  tasks:
    - name: create user2
      user:
        name: user2
        state: present

默认使用ansile-playbook  test.yml会执行失败

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

ERROR! Attempting to decrypt but no vault secrets found

查看加密的文件

[root@server ansible]# ansible-vault view test.yml
Vault password: 输入设置的密码redhat
---
- name: test1
  hosts: node1
  tasks:
    - name: create user2
      user:
        name: user2
        state: present

编辑现有的加密文件

[root@server ansible]# ansible-vault edit test.yml

加密现有的文件

Ansible-vault  encrypt a.yml

输入密码:redhat

确认密码:redhat

解密现有的文件

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

  1. 直接解密
ansible-vault decrypt test.yml
  1. 解密文件并存放为其他名称,原文件仍然处于加密状态(其中原文件a.yml仍处于加密状态,a-secret.yml处于解密状态)
ansible-vault  decrypt  a.yml  --output=a-secret.yml

更改加密文件的密码

ansible-vault  rekey  filename命令可以修改
ansible-vault  rekey  a.yml

输入旧密码

输入新密码

确认新密码

前面说到了加密后的文件直接用playbook执行会报错,那么该使用什么命令呢?

使用选项--vault-id @prompt或者--ask-vault-pass都可以

[root@server ansible]# ansible-playbook --vault-id @prompt a.yml
Vault password (default):
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create user1] ************************************************************
changed: [node1]
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@server ansible]# ansible-playbook --ask-vault-pass a.yml -C
Vault password:
PLAY [test] ********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [create user1] ************************************************************
changed: [node1]
PLAY RECAP *********************************************************************
node1                      : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0