文章目录

  • Ansible变量
  • 定义变量的方式
  • vars定义变量
  • vars_files变量
  • register注册变量
  • set_fact定义变量
  • 命令传入变量
  • 主机清单中的变量
  • 管理机密
  • 实例


Ansible变量

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

ansible中,可以将变量简化为三个范围

  • Global范围(高):从命令行和ansible配置设置的变量
  • play范围(中):在play和相关结构中设置的变量
  • Host范围(低):inventory、facts或register的变量,在主机组和个别主机上设置的变量

三个范围的变量优先级依次降低,如果变量重复定义,则以优先级高的为准


定义变量的方式

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

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

vars定义变量

---
- name: test
  hosts: node1
  vars:
    a: 111
    b: 222
    c:
      c1: 333
      c2: 444
  tasks:
    - name: debug1
      debug:
        msg: "{{ a }}"

    - name: debug2
      debug:
        msg: "{{ b }}"

    - name: debug3
      debug:
        msg: "{{ c }}"

    - name: debug4
      debug:
        msg: "{{ c.c1 }}"

    - name: debug5
      debug:
        msg: "{{ c.c2 }}"

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [debug1] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": 111
}

TASK [debug2] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": 222
}

TASK [debug3] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": {
        "c1": 333,
        "c2": 444
    }
}

TASK [debug4] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "333"
}

TASK [debug5] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "444"
}

PLAY RECAP ******************************************************************************************************************************************************************************************************
node1                      : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

vars_files变量

[student@ansible ansible]$ vim var.yml
---
a: 111
b: 222
c:
  c1: 333
  c2: 444

[student@ansible ansible]$ vim test.yml
---
- name: test
  hosts: node1
  vars_files: /home/student/ansible/var.yml
  tasks:
    - name: debug1
      debug:
        msg: "{{ a }}"

    - name: debug2
      debug:
        msg: "{{ b }}"

    - name: debug3
      debug:
        msg: "{{ c }}"

    - name: debug4
      debug:
        msg: "{{ c.c1 }}"

    - name: debug5
      debug:
        msg: "{{ c.c2 }}"

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [debug1] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": 111
}

TASK [debug2] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": 222
}

TASK [debug3] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": {
        "c1": 333,
        "c2": 444
    }
}

TASK [debug4] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "333"
}

TASK [debug5] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "444"
}

PLAY RECAP ******************************************************************************************************************************************************************************************************
node1                      : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

register注册变量

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

[student@ansible ansible]$ vim test.yml
---
- name: test
  hosts: node1
  tasks:
    - name: shell
      shell: "cat /tmp/kk"
      register: kk

    - name: debug
      debug:
        var: kk

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [shell] ****************************************************************************************************************************************************************************************************
changed: [node1]

TASK [debug] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "kk": {
        "changed": true,
        "cmd": "cat /tmp/kk",
        "delta": "0:00:00.003027",
        "end": "2022-10-28 21:04:45.181310",
        "failed": false,
        "rc": 0,
        "start": "2022-10-28 21:04:45.178283",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "",
        "stdout_lines": []
    }
}

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

[student@ansible ansible]$ vim test.yml
---
- name: test
  hosts: node1
  tasks:
    - name: shell
      shell: "cat /tmp/kk"
      register: kk

    - name: debug
      debug:
        msg: "{{ kk.rc }}"

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [shell] ****************************************************************************************************************************************************************************************************
changed: [node1]

TASK [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主机所有的事实变量

[student@ansible ansible]$ vim test.yml
---
- name: test
  hosts: node1
  tasks:
    - name: debug
      debug:
        msg: "{{ ansible_fqdn }}"

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [debug] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "node1.example.com"
}

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

命令传入变量

[student@ansible ansible]$ vim test.yml
---
- name: test
  hosts: node1
  tasks:
    - name: debug
      debug:
        msg: my name is {{ name1 }}

    - name: debug2
      debug:
        msg: my name is {{ name2 }}

[student@ansible ansible]$ ansible-playbook test.yml -e 'name1=aaa name2=bbb'

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [debug] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "my name is aaa"
}

TASK [debug2] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "my name is bbb"
}

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

主机清单中的变量

[student@ansible ansible]$ vim inventory
[dev]
node1 name1='aaa' name2='bbb'

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [debug] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "my name is aaa"
}

TASK [debug2] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "my name is bbb"
}

PLAY RECAP ******************************************************************************************************************************************************************************************************
node1                      : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[student@ansible ansible]$ vim inventory
[dev]
node1

[test]
node2

[prod]
node3

[webservers:children]
prod

[dev:vars]
name1= 'ccc'
name2= 'ddd'

[student@ansible ansible]$ ansible-playbook test.yml

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [debug] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "my name is ccc"
}

TASK [debug2] ***************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "my name is ddd"
}

PLAY RECAP ******************************************************************************************************************************************************************************************************
node1                      : ok=3    changed=0    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使用的结构化数据文件。

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

[student@ansible ansible]$ ansible-vault create n.yml
New Vault password:
Confirm New Vault password:

---
- name: test
  hosts: node1
  tasks:
    - name: test1
      debug:
        msg: test2

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

[student@ansible ansible]$ ansible-playbook n.yml
ERROR! Attempting to decrypt but no vault secrets found

查看加密的文件

[student@ansible ansible]$ ansible-vault view n.yml
Vault password:
---
- name: test
  hosts: node1
  tasks:
    - name: test1
      debug:
        msg: test2

编辑现有的加密文件

[student@ansible ansible]$ ansible-vault edit n.yml
Vault password:

加密现有的文件

[student@ansible ansible]$ ansible-vault encrypt aaaa.yml
New Vault password:
Confirm New Vault password:

解密现有的文件

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

更改加密文件的密码

ansible-vault rekey filename命令可以修改

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

[student@ansible ansible]$ ansible-playbook n.yml --vault-id @prompt
Vault password (default):

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [test1] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "test2"
}

PLAY RECAP ******************************************************************************************************************************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[student@ansible ansible]$ ansible-playbook n.yml --ask-vault-pass
Vault password:

PLAY [test] *****************************************************************************************************************************************************************************************************

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

TASK [test1] ****************************************************************************************************************************************************************************************************
ok: [node1] => {
    "msg": "test2"
}

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

实例

在ansible节点中新建/home/student/ansible/hwreport.empty的文件,文件内容为
hostname: inventoryhostname
mem: memory_in_MB
bios: BIOS_version
sda: disk_sda_size

创建一个名为 /home/student/ansible/hwreport.yml的 playbook,它将在所有受管节点上生成含有以下信息的输出文件 /root/hwreport.txt:

输出文件中的每一行含有一个 key=value 对。
您的 playbook 应当:
从 ansible节点中复制hwreport.empty文件到每台受控主机,并将它保存为/root/hwreport.txt
使用正确的值修改 /root/hwreport.txt
然后将/home/student/ansible/hwreport.yml这个playbook进行加密,加密的密码保存在/home/student/ansible/pass文件中,密码为abcdefg
执行该playbook,实现需求

[student@ansible ansible]$ vim hwreport.empty
hostname: inventoryhostname
mem: memory_in_MB
bios: BIOS_version
sda: disk_sda_size

[student@ansible ansible]$ vim hwreport.yml
---
- name: practice
  hosts: all
  tasks:
    - name: copy
      copy:
        src: /home/student/ansible/hwreport.empty
        dest: /root/hwreport.txt

    - name: notify hostname
      replace:
        path: /root/hwreport.txt
        regexp: inventoryhostname
        replace: "{{ ansible_hostname }}"

    - name: notify men
      replace:
        path: /root/hwreport.txt
        regexp: memory_in_MB
        replace: "{{ ansible_memtotal_mb }}"

    - name: notify bios
      replace:
        path: /root/hwreport.txt
        regexp: BIOS_version
        replace: "{{ ansible_bios_version }}"

    - name: notify sda
      replace:
        path: /root/hwreport.txt
        regexp: disk_sda_size
        replace: "{{ ansible_devices.sda.size }}"


[student@ansible ansible]$ echo "abcdefg" >pass
[student@ansible ansible]$ ansible-vault encrypt hwreport.yml
New Vault password:
Confirm New Vault password:
Encryption successful

[student@ansible ansible]$ ansible-playbook hwreport.yml --vault-id pass

PLAY [practice] *************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [node3]
ok: [node1]
ok: [node2]

TASK [copy] *****************************************************************************************************************************************************************************************************
changed: [node3]
changed: [node1]
changed: [node2]

TASK [notify hostname] ******************************************************************************************************************************************************************************************
changed: [node3]
changed: [node1]
changed: [node2]

TASK [notify men] ***********************************************************************************************************************************************************************************************
[WARNING]: The value 1785 (type int) in a string field was converted to '1785' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change.
changed: [node3]
changed: [node1]
changed: [node2]

TASK [notify bios] **********************************************************************************************************************************************************************************************
changed: [node3]
changed: [node1]
changed: [node2]

TASK [notify sda] ***********************************************************************************************************************************************************************************************
changed: [node3]
changed: [node1]
changed: [node2]

PLAY RECAP ******************************************************************************************************************************************************************************************************
node1                      : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node2                      : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3                      : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[student@ansible ansible]$ for i in node1 node2 node3; do ssh root@$i  cat /root/hwreport.txt; done
hostname: node1
mem: 1785
bios: 6.00
sda: 300.00 GB
hostname: node2
mem: 1785
bios: 6.00
sda: 300.00 GB
hostname: node3
mem: 1785
bios: 6.00
sda: 200.00 GB