如何在ansible中从变量文件中调用类似列表的值 [英] How to call list like values from the variable file in ansible
问题描述
我有一个可靠的剧本,我有多个参数要传递,这些参数有时足够长并且使播放看起来很胖,因此我正在考虑创建一个变量文件并将所有可能的值保留在该文件中以便调用它们从那里可以使播放变得更苗条,同时这将避免对剧本进行更改,我们可以对变量文件进行调整,例如 cloud_vars.yml
.
I have a ansible playbook where i have multiple parameters to be passed which are sometimes lengthy enough and makes play look fatty hence i'm thinking about creating a variable file and keeping all the possible values in that file so as to call them from there to make play slim and at the same time this will avoid making changes to the playbook and we can make adjustment to the variable file like 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
变量来自可变文件,因为它们在那里的列表中定义,到目前为止我已经对名称和位置等进行了硬编码.
Playbook Below
Below is the play which is setting facts
for later use in the playbook, i am looking forward to know as how to use azure_domains
azure_res_group
and azure_location
variable from the vaiable file as they are defined in a list there, as of now i have hard-coded the names and location etc.
$ 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 中是递归的,所以第一次 使用它们时,您将看到成功或可怕的 未定义变量!"
You can define those structures in your azure_vars.yml
file, including the jinja2 templates, but just with the knowledge that putting them in the vars file does not resolve them -- jinja2 template evaluation is recursive in ansible, so the first time they are used in when you will see either success or the dreaded "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 }}
将递归计算该表达式:
then after putting your azure_domain
into scope, use of {{ vnet }}
will recursively evaluate that expression:
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"
但是,正如我所说,您需要谨慎行事,因为胖手指不会有好下场:
But, as I said, you will need to exercise caution because a fat-finger will not end well:
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 中,以更高的详细程度运行确实可以找到根本原因:
But at least with my ansible 2.9.13, running at higher verbosity does surface the root cause:
ok: [localhost] => {
"vnet": "VARIABLE IS NOT DEFINED!: 'dict object' has no attribute 'us-yankee-doodle'"
}
这篇关于如何在ansible中从变量文件中调用类似列表的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!