You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拆分创建多OS/Flavor虚拟机的Ansible脚本为双配置文件

Correct Way to Split Your Ansible VM Creation Script into Main and Vars Files

Ah, I see where you went wrong here! The core issue is that with_items is a task-specific loop keyword, not a variable you can import directly. You need to refactor your VM instance list into a named variable, then reference that variable in your task's with_items parameter. Here's how to fix it:

Step 1: Fix vars.yaml – Define Your VM List as a Variable

Instead of using with_items directly, create a custom variable (e.g., vm_instances) that holds all your VM configurations:

---
vm_instances:
  - { name: Debian Jessie, image: Debian Jessie 8 , flavor: c1.small, loginame: debian }
  - { name: Debian Stretch, image: Debian Stretch 9 , flavor: c1.small, loginame: debian }
  - { name: ubuntu Xenial, image: Ubuntu Xenial 16.04 , flavor: c1.small, loginame: ubuntu }
  - { name: ubuntu Trusty, image: Ubuntu Trusty 14.04 , flavor: c1.small, loginame: ubuntu }
  - { name: Fedora, image: Fedora 25 , flavor: c1.small, loginame: fedora }
  - { name: CentOS, image: CentOS 7 , flavor: c1.small, loginame: centos }
  - { name: Rstudio, image: RStudio Appliance , flavor: c1.small, loginame: ubuntu }
  - { name: Spark Zepellin, image: Spark Zeppelin , flavor: m1.medium, loginame: ubuntu }

Step 2: Update main.yaml – Import Variables and Reference the VM List

You have two clean, valid options to import the variables and run the task:

This is the most straightforward approach—load the vars file directly in your play definition:

---
- hosts: localhost
  vars_files:
    - vars.yaml  # Loads the vm_instances variable into the play scope
  vars:
    http_port: 80
    max_clients: 200
  tasks:
    - name: Create VMs
      os_server:
        name: "{{ item.name }}"
        state: present
        image: "{{ item.image }}"
        boot_from_volume: True
        security_groups: ssh
        flavor: "{{ item.flavor }}"
        key_name: mykey
        region_name: "{{ lookup('env', 'OS_REGION_NAME') }}"
        nics:
          - net-name: private
        wait: yes
      register: instances
      with_items: "{{ vm_instances }}"  # Reference the imported variable here

Option 2: Import Variables via import_vars in Tasks

If you prefer to load variables within the task sequence (e.g., for conditional loading), use import_vars like this:

---
- hosts: localhost
  vars:
    http_port: 80
    max_clients: 200
  tasks:
    - name: Import VM configuration variables
      import_vars: vars.yaml  # Loads vm_instances into the play's variable scope
    - name: Create VMs
      os_server:
        name: "{{ item.name }}"
        state: present
        image: "{{ item.image }}"
        boot_from_volume: True
        security_groups: ssh
        flavor: "{{ item.flavor }}"
        key_name: mykey
        region_name: "{{ lookup('env', 'OS_REGION_NAME') }}"
        nics:
          - net-name: private
        wait: yes
      register: instances
      with_items: "{{ vm_instances }}"  # Reference the imported variable

Why Your Original Approach Failed

Your vars.yaml used with_items as a top-level key, but Ansible doesn't recognize that as a valid variable. with_items is only valid as part of a task definition—you can't store it in a vars file. By wrapping your VM list in a named variable, you make it accessible to the task's with_items directive, which is where the loop logic belongs.

内容的提问来源于stack exchange,提问作者benice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:24:56