ansible变量
定义变量规则:由字母/数字/下划线组成,变量需要以字母开头,ansible内置的关键字不能作为变量名。
ansible中,可以将变量简化为三个范围Global范围(高):从命令行和ansible配置设置的变量play范围(中):在play和相关结构中设置的变量Host范围(低):inventory、facts或register的变量,在主机组和个别主机上设置的变量三个范围的变量优先级依次升高,如果变量重复定义,则以优先级高的为准
注册和定义变量的各种方式
ansible中定义变量的方式有很多种,大致有:
- 将模块的执⾏结果注册为变量;
- 直接定义字典类型的变量;
- role中⽂件内定义变量;
- 命令⾏传递变量;
- 借助with_items迭代将多个task的结果赋值给⼀个变量;
- inventory中的主机或主机组变量;
- 内置变量。
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选项以其他名称保存解密文件。
- 直接解密
ansible-vault decrypt test.yml
- 解密文件并存放为其他名称,原文件仍然处于加密状态(其中原文件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