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

查看:42
本文介绍了如何在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"
...

下方的剧本

下面是设置事实以供以后在剧本中使用的剧本,我很期待知道如何使用 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模板评估是递归的,因此,第一次使用它们时,您将看到成功或可怕的未定义变量!"

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_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!"
}

但是至少在我的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天全站免登陆