如何在ansible中从变量文件中调用类似列表的值 [英] How to call list like values from the variable file in ansible

查看:18
本文介绍了如何在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_groupazure_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆