跳到主要内容

[toc]

ansible定义变量

ansible2.9变量官方文档

1.ansible定义变量

1.1 在playbook中的play进行定义

在yml文件中通过 vars 关键字定义变量,引用变量使用 {{}}

vars:
- 变量名1: 变量值1
- 变量名2: 变量值2

使用示例

- hosts: all
vars:
- pkg_name1: httpd
- pkg_name2: nginx

tasks:
- name: install httpd
yum:
name:
- "{{ pkg_name1 }}"
- "{{ pkg_name2 }}"
state:
present

在playbook中还可以通过 vars_files 关键字引用变量文件

vars_files: 变量文件

编辑一个变量文件

pkg_name1: httpd
pkg_name2: nginx

在yml文件使用关键字 vars_files 引用变量文件

- hosts: devops02

vars_files:
./vars_pub.yml

tasks:
- name: install httpd nginx
yum:
name:
- "{{ pkg_name1 }}"
- "{{ pkg_name2 }}"
state:
present

1.2 通过inventory主机清单进行定义

在inventory主机清单中通过 [组名:vars] 定义变量,这个变量既可以在inventory中引用,也可以在playbook中引用

[all_server:vars]
ansible_ssh_user=ops
ansible_ssh_port=2233
ansible_ssh_private_key_file=/home/ops/.ssh/id_rsa_ops
ansible_become=true
ansible_become_method=sudo
ansible_become_user=root

[all_server]
devops01
devops02

1.2.1 group_varshost_vars

官方推荐在项目目录下,创建两个变量目录 host_varsgroup_vars ,在这2个目录下存放变量的文件

  • 在组(group_vars)下面创建一个和inventory中组名相同的变量文件,那么inventory中某个组下面的主机就会引用 group_vars 目录下与组名同名的变量文件中的变量

  • 在主机(host_vars)下面创建一个和inventory中主机名相同的变量文件,那么invertory中的某个主机就会引用 host_vars 目录下和主机同名的变量文件中的变量

1.2.1.1 group_vars 使用示例

在项目下创建 group_vars 目录

mkdir group_vars

项目下hosts文件内容如下

[devops]
devops01
devops02

group_vars 目录下创建与组名同名的文件并写入变量

cat > group_vars/devops <<EOF
pkg_name1: nginx
pkg_name2: httpd
EOF

编辑yml文件

cat > vars01.yml <<EOF
- hosts: devops

tasks:
- name: install httpd nginx
yum:
name:
- "{{ pkg_name1 }}"
- "{{ pkg_name2 }}"
state:
present
EOF

执行playbook,可以看到在yml文件中没有指定变量文件的情况下会自动读取 group_vars 目录下与invertory中组名同名的变量文件中的变量

$ ansible-playbook vars01.yml -i hosts

PLAY [devops] ******************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [devops02]
ok: [devops01]

TASK [install httpd nginx] *****************************************************************************************************************************
ok: [devops02]
ok: [devops01]

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

1.2.1.2 host_vars 使用示例

在项目下创建 host_vars 目录

mkdir host_vars

项目下hosts文件内容如下

[devops]
devops01

host_vars 目录下创建与主机同名的文件并写入变量

cat > host_vars/devops01 <<EOF
pkg_name1: nginx
pkg_name2: httpd
EOF

编辑yml文件

cat > vars02.yml <<EOF
- hosts: devops01

tasks:
- name: install httpd nginx
yum:
name:
- "{{ pkg_name1 }}"
- "{{ pkg_name2 }}"
state:
present
EOF

执行playbook,可以看到在yml文件中没有指定变量文件的情况下会自动读取 host_vars 目录下与invertory中主机名同名的变量文件中的变量

$ ansible-playbook vars02.yml -i hosts

PLAY [devops01] ****************************************************************************************************************************************

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

TASK [install httpd nginx] *****************************************************************************************************************************
ok: [devops01]

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

1.2.2 特殊组 all

group_varshost_vars 有一个共同的缺点,如果有多个组或者多台主机的话,那就得编辑多个变量文件,即使变量文件内容一致也需要编辑多个与组名相同的变量文件,这样的话就会有很多重复的工作

例如在 group_vars 目录下有2个与组名相同的变量文件v1与v2,v1与v2文件内容是相同的,但是v1与v2不能互相调用对方的变量,此时使用 all 这个组就可以解决这个问题

项目下 hosts 文件内容如下

[d1]
devops01

[d2]
devops02

host_vars 目录下创建 all 组并写入变量

cat > group_vars/all <<EOF
pkg_name1: nginx
pkg_name2: httpd
EOF

编辑yml文件d1

cat > d1.yml <<EOF
- hosts: d1

tasks:
- name: install httpd nginx
yum:
name:
- "{{ pkg_name1 }}"
- "{{ pkg_name2 }}"
state:
present
EOF

执行playbook,可以从 group_vars 目录下读取 all 组中的变量

$ ansible-playbook d1.yml -i hosts

PLAY [d1] **********************************************************************************************************************************************

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

TASK [install httpd nginx] *****************************************************************************************************************************
ok: [devops01]

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

编辑yml文件d2

cat > d2.yml <<EOF
- hosts: d2

tasks:
- name: install httpd nginx
yum:
name:
- "{{ pkg_name1 }}"
- "{{ pkg_name2 }}"
state:
present
EOF

执行playbook,可以从 group_vars 目录下读取 all 组中的变量

$ ansible-playbook d2.yml -i hosts

PLAY [d2] **********************************************************************************************************************************************

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

TASK [install httpd nginx] *****************************************************************************************************************************
ok: [devops02]

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

playbook指定执行单个主机的时候,会先从 host_vars 下查找变量,如果没有就从 group_vars 中查找,最后从 group_vars/all 中查找

1.3 通过执行playbook时进行定义

执行playbook通过 -e 参数指定变量

项目下hosts文件内容如下

[prod]
devops01

[test]
devops02

编辑yml文件,主机处定义一个变量,在执行playbook的时候通过 -e 参数指定要执行的主机组

cat > var.yml <<EOF
- hosts: "{{ hosts }}"

tasks:
- name: install nginx
yum:
name:
- nginx
state:
present
EOF

执行playbook的时候,通过 -e 指定要执行的主机组

$ ansible-playbook -i hosts var.yml -e "hosts=prod"
[WARNING]: Found variable using reserved name: hosts

PLAY [prod] ********************************************************************************************************************************************

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

TASK [install nginx] ***********************************************************************************************************************************
ok: [devops01]

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

2.ansible变量优先级

-e 传参 > vars_files(playbook) > vars(playbook) > host_vars(inventory) > group_vars(inventory)> 特殊组all