使用 Ansible 启动 EC2 实例并动态分配子网

Launch EC2 instances using Ansible and assign subnets dynamically

您好,我需要编写一个 Ansible 代码来启动 EC2 实例并以循环方式将它们分配给可用的子网。只有 1 个 VPC 是手动创建的,但是子网的数量会根据启动的基础设施而变化。 我的主机文件如下所示

[ABC-database]
ABCDB01

[ABC-application]
ABCFE0[1:2]
ABCBE0[1:2]

[cassandra]
CASS0[1:3]

我也写过创建子网文件的代码

subnet1: subnet-7284c12b
subnet2: subnet-fd363e98
subnet3: subnet-c892bfbf

我要做的是一次选择一个实例,从 all.yml 中选择每个实例的配置,并以循环(循环)方式将其分配给每个子网。

目前我已经编写了一个 shell 脚本来执行此操作。脚本计算子网文件中的子网数量,每次调用时 returns 一个新的子网 ID。

我被卡住了。 我应该如何在启动 ec2 实例时调用此脚本? 下面的代码会引发错误 'next_subnet' 未定义

- name: Launch instances.
  local_action:
    command: ./get_next_available_subnet.sh
    register: next_subnet
    module: ec2
    region: "{{ region }}"
    keypair: "{{ keypair }}"
    instance_type: "{{item.instance_type}}"
    image: "{{image_id}}"
    vpc_subnet_id: "{{ next_subnet.stdout }}"
    count: 1
    wait: yes
  with_items: "{{component_list}}"

有没有更简单的方法来实现这个目标?

您的剧本已将两个任务合并为一个,因此当您尝试 运行 ec2 任务时,next_subnet 变量未注册。

将您的剧本更改为此可以解决紧迫的问题:

- name: Get next subnet
  local_action:
    command: ./get_next_available_subnet.sh
    register: next_subnet

- name: Launch instances
  local_action:
    ec2:
      region: "{{ region }}"
      keypair: "{{ keypair }}"
      instance_type: "{{item.instance_type}}"
      image: "{{image_id}}"
      vpc_subnet_id: "{{ next_subnet.stdout }}"
      count: 1
      wait: yes
  with_items: "{{component_list}}"

但是,这只会使剧本 运行 而不是您想要的。如果你增加 count 数量,每个实例仍然被放在同一个子网中,因为 next_subnet 变量只注册一次,然后你在循环中使用它。

假设您可以一遍又一遍地调用您的脚本,并且它将在可用的子网 ID 之间轮换,那么您只需要迭代第一个任务以获得一个结果列表,您可以将其用于第二个任务,如下所示:

- name: Get next subnet
  local_action:
    command: ./get_next_available_subnet.sh
    register: next_subnet
  with_items: component_list

- name: Launch instances
  local_action:
    ec2:
      region: "{{ region }}"
      keypair: "{{ keypair }}"
      instance_type: "{{item.1.instance_type}}"
      image: "{{image_id}}"
      vpc_subnet_id: "{{ item.0.stdout }}"
      count: 1
      wait: yes
  with_together: 
    - next_subnet
    - component_list

假设您的 shell 脚本输出如下内容:

$ ./get_next_available_subnet.sh
subnet-7284c12b
$ ./get_next_available_subnet.sh
subnet-fd363e98
$ ./get_next_available_subnet.sh
subnet-c892bfbf
$ ./get_next_available_subnet.sh
subnet-7284c12b

然后第一个任务将注册 next_subnet 的变量到一个任务结果列表,该列表将有一个键 stdout 和一个子网 ID 的值。然后,第二个任务使用 with_together loop 遍历该子网 ID 列表以及实例列表。