如何从ansible中的变量文件中调用类似值的列表
How to call list like values from the variable file in ansible
我有一个 ansible 剧本,其中我有多个参数要传递,这些参数有时足够长并且使游戏看起来很胖,因此我正在考虑创建一个变量文件并将所有可能的值保留在该文件中,以便从那里调用它们以使游戏变苗条,同时这将避免对剧本进行更改,我们可以像 cloud_vars.yml
.
一样对变量文件进行调整
下面是我的变量文件:
$ cat azure_vars.yml
---
azure_subnet_name: "infra"
azure_os_disk_type: Standard_LRS
azure_nprod_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg001/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod03_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg002/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod02_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
public_key: "ssh-rsa:XXXX "
azure_image_id: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/mgt01-rg001/providers/Microsoft.Compute/galleries/imagegallery/images/myimage/versions/0.0.3"
# Azure domains
azure_domains:
- "eu-azrc1"
- "us-azrc2"
- "us-sea01"
# Resource group
azure_res_group:
- "rg001"
- "rg002"
- "rg003"
# Azure locations
azure_location:
- "westus2"
- "westeurope"
- "southcentralus"
...
下面的剧本
下面是设置facts
的剧本,供以后在剧本中使用,我很期待知道如何使用azure_domains
azure_res_group
和azure_location
来自 vaiable 文件的变量,因为它们在列表中定义,截至目前,我已经对名称和位置等进行了硬编码。
$ cat new_vm_Creation.yml
---
- name: create azure vm
hosts: localhost
connection: local
tasks:
- include_vars: azure_vars.yml
- set_fact:
host: "{{ azure_vm_name.split('.') }}"
- set_fact:
azure_domain: "{{ host.1 }}.{{ host.2 }}"
- name: azure_domain
debug:
msg: "{{ azure_domain }}"
- set_fact:
azure_location: "westus2"
when: azure_domain == "us-sea01"
- set_fact:
azure_location: "westeurope"
when: azure_domain == "eu-azrc1"
- set_fact:
azure_location: "southcentralus"
when: azure_domain == "us-azrc2"
- name: azure_location
debug:
msg: "{{ azure_location }}"
- set_fact:
res_group: "rg001"
when: azure_domain == "us-sea01"
- set_fact:
res_group: "rg002"
when: azure_domain == "eu-azrc1"
- set_fact:
res_group: "rg003"
when: azure_domain == "us-azrc2"
- name: Resource Group
debug:
msg: "{{ res_group }}"
- set_fact:
vnet: "{{ azure_nprod_vnet }}"
when: azure_domain == "us-sea01"
- set_fact:
vnet: "{{ azure_prod03_vnet }}"
when: azure_domain == "eu-azrc1"
- set_fact:
vnet: "{{ azure_prod02_vnet }}"
when: azure_domain == "us-azrc2"
- name: Vnet
debug:
msg: "{{ vnet }}"
- name: create network security group that allows ssh
azure_rm_securitygroup:
resource_group: "{{ res_group }}"
location: "{{ location }}"
name: "{{ azure_vm_name }}-nsg"
rules:
- name: ssh
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: create virtual network interface card
azure_rm_networkinterface:
resource_group: "{{ res_group }}"
location: "{{ location }}"
name: "{{ azure_vm_name }}-nic1"
subnet: "{{ azure_subnet_name }}"
virtual_network: "{{ vnet }}"
security_group: "{{ azure_vm_name }}-nsg"
enable_accelerated_networking: true
public_ip: no
state: present
- name: create vm
azure_rm_virtualmachine:
resource_group: "{{ res_group }}"
location: "{{ location }}"
name: "{{ azure_vm_name }}"
vm_size: Standard_D4s_v3
admin_username: some_id
ssh_password_enabled: false
ssh_public_keys:
- path: /home/some_id/.ssh/authorized_keys
key_data: "{{ public_key }}"
network_interfaces: "{{ azure_vm_name }}-nic1"
os_disk_name: "{{ azure_vm_name }}-osdisk"
managed_disk_type: "{{ azure_os_disk_type }}"
os_disk_caching: ReadWrite
os_type: Linux
image:
id: "{{ azure_image_id }}"
publisher: redhat
plan:
name: rhel-lvm78
product: rhel-byos
publisher: redhat
...
您可以在 azure_vars.yml
文件中定义这些结构,包括 jinja2 模板,但只要知道将它们放在 vars 文件中 并不能解析它们 -- jinja2 模板评估在 ansible 中是递归的,所以第一次使用它们 时你会看到成功或可怕的 "VARIABLE IS NOT DEFINED!"
给定 azure_vars.yml
的
azure_nprod_vnet: "/subscriptions/alpha-nprod/resourceGroups/rg001/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod03_vnet: "/subscriptions/beta-prod03/resourceGroups/rg002/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod02_vnet: "/subscriptions/charlie-prod02/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
things_by_azure_domain:
"us-sea01":
azure_location: "westus2"
res_group: "rg001"
vnet: "{{ azure_nprod_vnet }}"
"eu-azrc1":
azure_location: "westeurope"
res_group: "rg002"
vnet: "{{ azure_prod03_vnet }}"
"us-azrc2":
azure_location: "southcentralus"
res_group: "rg003"
vnet: "{{ azure_prod02_vnet }}"
vnet: "{{ things_by_azure_domain[azure_domain].vnet }}"
然后在将 azure_domain
放入作用域后,使用 {{ vnet }}
将递归地计算该表达式:
tasks:
# OBSERVE that we can include this, even with `azure_domain` not yet defined
# because `include_vars` DOES NOT evaluate those jinja2 expressions
- include_vars: azure_vars.yml
- set_fact:
azure_domain: us-azrc2
- debug:
var: vnet
屈服
ok: [localhost] => {
"vnet": "/subscriptions/charlie-prod02/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
但是,正如我所说,您需要谨慎行事,因为 fat-finger 不会有好的结局:
tasks:
- include_vars: azure_vars.yml
- set_fact:
azure_domain: us-yankee-doodle
- debug:
var: vnet
产量
ok: [localhost] => {
"vnet": "VARIABLE IS NOT DEFINED!"
}
但至少在我的 ansible 2.9.13 中,运行 在更高的冗长程度下确实浮出了根本原因:
ok: [localhost] => {
"vnet": "VARIABLE IS NOT DEFINED!: 'dict object' has no attribute 'us-yankee-doodle'"
}
我喜欢 @mdaniel
的想法,但我不知道以后谁可以将它们添加到您的 playbook
中用于不同 tasks
:
根据你的post,你可以稍微对齐你的azure_vars.yml
,以便让它们都按相同的顺序排列,这将有助于稍后在游戏中轻松调用它们。
因此,我将美国区域排在最前面,欧洲排在最后。
变量文件:
# Azure domains
azure_domains:
- us-sea01
- us-azrc2
- eu-azrc1
# Resource group
azure_res_group:
- rg001
- rg002
- rg003
# Azure locations
azure_location:
- westus2
- southcentralus
- westeurope
...
播放:
现在你可以稍微让你的Playbook
更苗条,这将帮助你只修改azure_vars.yml
而不是在游戏中。
---
- name: create azure vm
hosts: localhost
connection: local
tasks:
- include_vars: azure_vars.yml
- set_fact:
host: "{{ azure_vm_name.split('.') }}"
- set_fact:
domain: "{{ host.1 }}.{{ host.2 }}"
- name: Domain
debug:
msg: "{{ domain }}"
- set_fact:
location: "{{ azure_location[0] }}"
when: 'domain == azure_domain[0]'
- set_fact:
location: "{{ azure_location[1] }}"
when: 'domain == azure_domain[1]'
- set_fact:
location: "{{ azure_location[2] }}"
when: 'domain == azure_domain[2]'
- name: Location
debug:
msg: "{{ location }}"
- set_fact:
res_group: "{{ azure_res_group[0] }}"
when: 'domain == azure_domain[0]'
- set_fact:
res_group: "{{ azure_res_group[1] }}"
when: 'domain == azure_domain[1]'
- set_fact:
res_group: "{{ azure_res_group[2] }}"
when: 'domain == azure_domain[2]'
- name: Resource Group
debug:
msg: "{{ res_group }}"
- set_fact:
vnet: "{{ azure_nprod_vnet }}"
when: 'domain == azure_domain[0]'
- set_fact:
vnet: "{{ azure_prod03_vnet }}"
when: 'domain == azure_domain[2]'
- set_fact:
vnet: "{{ azure_prod02_vnet }}"
when: 'domain == azure_domain[1]'
- name: Vnet
debug:
msg: "{{ vnet }}"
我有一个 ansible 剧本,其中我有多个参数要传递,这些参数有时足够长并且使游戏看起来很胖,因此我正在考虑创建一个变量文件并将所有可能的值保留在该文件中,以便从那里调用它们以使游戏变苗条,同时这将避免对剧本进行更改,我们可以像 cloud_vars.yml
.
下面是我的变量文件:
$ cat azure_vars.yml
---
azure_subnet_name: "infra"
azure_os_disk_type: Standard_LRS
azure_nprod_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg001/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod03_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg002/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod02_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
public_key: "ssh-rsa:XXXX "
azure_image_id: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/mgt01-rg001/providers/Microsoft.Compute/galleries/imagegallery/images/myimage/versions/0.0.3"
# Azure domains
azure_domains:
- "eu-azrc1"
- "us-azrc2"
- "us-sea01"
# Resource group
azure_res_group:
- "rg001"
- "rg002"
- "rg003"
# Azure locations
azure_location:
- "westus2"
- "westeurope"
- "southcentralus"
...
下面的剧本
下面是设置facts
的剧本,供以后在剧本中使用,我很期待知道如何使用azure_domains
azure_res_group
和azure_location
来自 vaiable 文件的变量,因为它们在列表中定义,截至目前,我已经对名称和位置等进行了硬编码。
$ cat new_vm_Creation.yml
---
- name: create azure vm
hosts: localhost
connection: local
tasks:
- include_vars: azure_vars.yml
- set_fact:
host: "{{ azure_vm_name.split('.') }}"
- set_fact:
azure_domain: "{{ host.1 }}.{{ host.2 }}"
- name: azure_domain
debug:
msg: "{{ azure_domain }}"
- set_fact:
azure_location: "westus2"
when: azure_domain == "us-sea01"
- set_fact:
azure_location: "westeurope"
when: azure_domain == "eu-azrc1"
- set_fact:
azure_location: "southcentralus"
when: azure_domain == "us-azrc2"
- name: azure_location
debug:
msg: "{{ azure_location }}"
- set_fact:
res_group: "rg001"
when: azure_domain == "us-sea01"
- set_fact:
res_group: "rg002"
when: azure_domain == "eu-azrc1"
- set_fact:
res_group: "rg003"
when: azure_domain == "us-azrc2"
- name: Resource Group
debug:
msg: "{{ res_group }}"
- set_fact:
vnet: "{{ azure_nprod_vnet }}"
when: azure_domain == "us-sea01"
- set_fact:
vnet: "{{ azure_prod03_vnet }}"
when: azure_domain == "eu-azrc1"
- set_fact:
vnet: "{{ azure_prod02_vnet }}"
when: azure_domain == "us-azrc2"
- name: Vnet
debug:
msg: "{{ vnet }}"
- name: create network security group that allows ssh
azure_rm_securitygroup:
resource_group: "{{ res_group }}"
location: "{{ location }}"
name: "{{ azure_vm_name }}-nsg"
rules:
- name: ssh
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: create virtual network interface card
azure_rm_networkinterface:
resource_group: "{{ res_group }}"
location: "{{ location }}"
name: "{{ azure_vm_name }}-nic1"
subnet: "{{ azure_subnet_name }}"
virtual_network: "{{ vnet }}"
security_group: "{{ azure_vm_name }}-nsg"
enable_accelerated_networking: true
public_ip: no
state: present
- name: create vm
azure_rm_virtualmachine:
resource_group: "{{ res_group }}"
location: "{{ location }}"
name: "{{ azure_vm_name }}"
vm_size: Standard_D4s_v3
admin_username: some_id
ssh_password_enabled: false
ssh_public_keys:
- path: /home/some_id/.ssh/authorized_keys
key_data: "{{ public_key }}"
network_interfaces: "{{ azure_vm_name }}-nic1"
os_disk_name: "{{ azure_vm_name }}-osdisk"
managed_disk_type: "{{ azure_os_disk_type }}"
os_disk_caching: ReadWrite
os_type: Linux
image:
id: "{{ azure_image_id }}"
publisher: redhat
plan:
name: rhel-lvm78
product: rhel-byos
publisher: redhat
...
您可以在 azure_vars.yml
文件中定义这些结构,包括 jinja2 模板,但只要知道将它们放在 vars 文件中 并不能解析它们 -- jinja2 模板评估在 ansible 中是递归的,所以第一次使用它们 时你会看到成功或可怕的 "VARIABLE IS NOT DEFINED!"
给定 azure_vars.yml
的
azure_nprod_vnet: "/subscriptions/alpha-nprod/resourceGroups/rg001/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod03_vnet: "/subscriptions/beta-prod03/resourceGroups/rg002/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod02_vnet: "/subscriptions/charlie-prod02/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
things_by_azure_domain:
"us-sea01":
azure_location: "westus2"
res_group: "rg001"
vnet: "{{ azure_nprod_vnet }}"
"eu-azrc1":
azure_location: "westeurope"
res_group: "rg002"
vnet: "{{ azure_prod03_vnet }}"
"us-azrc2":
azure_location: "southcentralus"
res_group: "rg003"
vnet: "{{ azure_prod02_vnet }}"
vnet: "{{ things_by_azure_domain[azure_domain].vnet }}"
然后在将 azure_domain
放入作用域后,使用 {{ vnet }}
将递归地计算该表达式:
tasks:
# OBSERVE that we can include this, even with `azure_domain` not yet defined
# because `include_vars` DOES NOT evaluate those jinja2 expressions
- include_vars: azure_vars.yml
- set_fact:
azure_domain: us-azrc2
- debug:
var: vnet
屈服
ok: [localhost] => {
"vnet": "/subscriptions/charlie-prod02/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
但是,正如我所说,您需要谨慎行事,因为 fat-finger 不会有好的结局:
tasks:
- include_vars: azure_vars.yml
- set_fact:
azure_domain: us-yankee-doodle
- debug:
var: vnet
产量
ok: [localhost] => {
"vnet": "VARIABLE IS NOT DEFINED!"
}
但至少在我的 ansible 2.9.13 中,运行 在更高的冗长程度下确实浮出了根本原因:
ok: [localhost] => {
"vnet": "VARIABLE IS NOT DEFINED!: 'dict object' has no attribute 'us-yankee-doodle'"
}
我喜欢 @mdaniel
的想法,但我不知道以后谁可以将它们添加到您的 playbook
中用于不同 tasks
:
根据你的post,你可以稍微对齐你的azure_vars.yml
,以便让它们都按相同的顺序排列,这将有助于稍后在游戏中轻松调用它们。
因此,我将美国区域排在最前面,欧洲排在最后。
变量文件:
# Azure domains
azure_domains:
- us-sea01
- us-azrc2
- eu-azrc1
# Resource group
azure_res_group:
- rg001
- rg002
- rg003
# Azure locations
azure_location:
- westus2
- southcentralus
- westeurope
...
播放:
现在你可以稍微让你的Playbook
更苗条,这将帮助你只修改azure_vars.yml
而不是在游戏中。
---
- name: create azure vm
hosts: localhost
connection: local
tasks:
- include_vars: azure_vars.yml
- set_fact:
host: "{{ azure_vm_name.split('.') }}"
- set_fact:
domain: "{{ host.1 }}.{{ host.2 }}"
- name: Domain
debug:
msg: "{{ domain }}"
- set_fact:
location: "{{ azure_location[0] }}"
when: 'domain == azure_domain[0]'
- set_fact:
location: "{{ azure_location[1] }}"
when: 'domain == azure_domain[1]'
- set_fact:
location: "{{ azure_location[2] }}"
when: 'domain == azure_domain[2]'
- name: Location
debug:
msg: "{{ location }}"
- set_fact:
res_group: "{{ azure_res_group[0] }}"
when: 'domain == azure_domain[0]'
- set_fact:
res_group: "{{ azure_res_group[1] }}"
when: 'domain == azure_domain[1]'
- set_fact:
res_group: "{{ azure_res_group[2] }}"
when: 'domain == azure_domain[2]'
- name: Resource Group
debug:
msg: "{{ res_group }}"
- set_fact:
vnet: "{{ azure_nprod_vnet }}"
when: 'domain == azure_domain[0]'
- set_fact:
vnet: "{{ azure_prod03_vnet }}"
when: 'domain == azure_domain[2]'
- set_fact:
vnet: "{{ azure_prod02_vnet }}"
when: 'domain == azure_domain[1]'
- name: Vnet
debug:
msg: "{{ vnet }}"