如何拆分创建多OS/Flavor虚拟机的Ansible脚本为双配置文件
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:
Option 1: Import Variables via vars_files (Recommended for Play-Level Variables)
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

