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

时间:2016-02-11 10:48:33

标签: amazon-web-services amazon-ec2 ansible vpc

您好我需要编写一个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脚本来执行此操作。该脚本计算子网文件中的子网数,并在每次调用时返回新的子网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}}"

是否有一种不那么混乱的方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

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

将剧本改为此可以解决这个直接问题:

- 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列表以及实例列表。