我正在为实践教程课程设置最多 150 台临时 EC2 服务器。
我成功地动态创建了 EC2 清单,并针对创建的实例运行角色来配置所有内容,但我需要为每个实例设置一个简单的主机名。为此,我有一个文件,其中包含我想用作主机名的简单名称列表。这是我的剧本:
---
- hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Provision a set of instances
ec2:
key_name: ubuntu
instance_type: t2.micro
image: "{{ ami_id }}"
wait: true
exact_count: {{ server_count }}
count_tag:
Name: Tutorial
instance_tags:
Name: Tutorial
groups: ['SSH', 'Web']
register: ec2
- name: Add all instance public IPs to host group
add_host: hostname={{ item.public_ip }} groups=ec2hosts
loop: "{{ ec2.instances }}"
- name: Set a host name for each instance in DNS
route53:
zone: {{ tutorial_domain }}
record: "name.{{ tutorial_domain }}"
state: present
type: A
ttl: 120
value: {{ item.public_ip }}
wait: yes
loop: "{{ ec2.instances }}"
它实际上归结为那一record: "name.{{ tutorial_domain }}"
行 - 我如何在我的名字列表中查找一个名字并将其用作主机名,name
变成{{ some_dynamic_name }}
?
我见过查找插件,但它们似乎都专注于循环遍历某个外部文件的全部内容 - 但我已经循环遍历了服务器列表,并且该列表可能比名称列表短(例如,我可能只有 10 个服务器)。理想情况下,我想将名称列表读入数组一次,然后使用服务器循环中的索引来选择名称(即,第三个服务器将获得第三个名称)。我如何在 ansible 中做到这一点?或者有更好的方法吗?
答案1
您可以使用zip
过滤器将实例列表与名称列表组合起来,如下所示:
---
- hosts: localhost
gather_facts: false
vars:
tutorial_domain: example.com
ec2:
instances:
- public_ip: 1.2.3.4
- public_ip: 2.3.4.5
names:
- blue-duck
- red-panda
tasks:
- debug:
msg:
route53:
zone: "{{ tutorial_domain }}"
record: "{{ item.1 }}.{{tutorial_domain}}"
state: present
type: A
ttl: 120
value: "{{ item.0.public_ip }}"
wait: yes
loop: "{{ ec2.instances|zip(names)|list }}"
在旧版本的 Ansible 中,您可以使用循环完成相同的操作with_together
。
答案2
另一种方法是使用循环索引来循环多个列表。这样,在列表中添加偏移量将更加容易。
- set_fact:
ips: ['1.2.3.4', '5.6.7.8']
hostnames: ['host1', 'host2']
- debug:
msg: "ip={{ ips[index] }}, hostname={{ hostnames[index] }}"
loop: "{{ ips }}"
loop_control:
index_var: index