我正在尝试创建一个AWS EC2 ansible playbook:
1)首先在三个区域分配一个VPC:us-west-1,ap-northeast-1和eu-west-1 .
2)找到每个区域的最新ubuntu AMI(ec2_ami_search),
3)然后使用1)和2)中发现的结果,使用最新的ubuntu AMI(针对该地区)为每个区域创建一个EC2实例,其中包含可用区域us-west-1a,ap-northeast-1a和eu-west-1a , 分别 .
使用Ansible,我对步骤1)和2)没有任何问题,这简单地说:
>
tasks:
- name: create a vpc
ec2_vpc:
state: present
region: "{{ item.region }}"
internet_gateway: True
resource_tags: { env: production}
cidr_block: 10.0.0.0/16
subnets:
- cidr: 10.0.0.0/24
az: "{{ item.az }}"
resource_tags:
env: production
tier: public
route_tables:
- subnets:
- 10.0.0.0/24
routes:
- dest: 0.0.0.0/0
gw: igw
with_items:
- region: us-west-1
az: us-west-1a
- region: ap-northeast-1
az: ap-northeast-1a
- region: eu-west-1
az: eu-west-1a
...
- name: Get the ubuntu trusty AMI
ec2_ami_search: distro=ubuntu release=trusty virt=hvm region={{ item }}
with_items:
- us-west-1
- ap-northeast-1
- eu-west-1
register: ubuntu_image
...
>
并使用调试模块输出ubuntu_image变量:
TASK: [print out ubuntu images] ***********************************************
ok: [localhost] => {
"ubuntu_image": {
"changed": false,
"msg": "All items completed",
"results": [
{
"aki": null,
"ami": "ami-b33dccf7",
"ari": null,
"changed": false,
"invocation": {
"module_args": "distro=ubuntu release=trusty virt=hvm region=us-west-1",
"module_name": "ec2_ami_search"
},
"item": "us-west-1",
"serial": "20150629",
"tag": "release"
},
{
"aki": null,
"ami": "ami-9e5cff9e",
"ari": null,
"changed": false,
"invocation": {
"module_args": "distro=ubuntu release=trusty virt=hvm region=ap-northeast-1",
"module_name": "ec2_ami_search"
},
"item": "ap-northeast-1",
"serial": "20150629",
"tag": "release"
},
{
"aki": null,
"ami": "ami-7c4b0a0b",
"ari": null,
"changed": false,
"invocation": {
"module_args": "distro=ubuntu release=trusty virt=hvm region=eu-west-1",
"module_name": "ec2_ami_search"
},
"item": "eu-west-1",
"serial": "20150629",
"tag": "release"
}
]
}
}
但是,我无法弄清楚如何使步骤3)从ubuntu_image寄存器变量中获取结果,然后确定给定EC2实例所属的3个AMI和子网中的哪一个 . 请参阅下面的解决方法,我手动硬编码了ami和子网值,我只是从上面的ubuntu_image打印输出中打印出来的:
- name: start the instances
ec2:
image: "{{ item.ami }}" # MANUALLY HARDCODED
region: "{{ item.region }}"
instance_type: "{{ instance_type }}"
assign_public_ip: True
key_name: "{{ item.name }}"
group: ["http deployment", "ssh deployment", "outbound deployment"]
instance_tags: { Name: "{{ item.name }}", type: ss, env: production}
exact_count: "{{ count }}"
count_tag: { Name: "{{ item.name }}" }
vpc_subnet_id: "{{ item.subnet }}" #MANUALLY HARDCODED
wait: yes
register: ec2
with_items:
- region: us-west-1
name: ss12
ami: ami-b33dccf7 # MANUALLY HARDCODED
subnet: subnet-35a22550 # MANUALLY HARDCODED
- region: ap-northeast-1
name: ss21
ami: ami-9e5cff9e # MANUALLY HARDCODED
subnet: subnet-88c47dff # MANUALLY HARDCODED
- region: eu-west-1
name: ss32
ami: ami-7c4b0a0b # MANUALLY HARDCODED
subnet: subnet-23f59554 # MANUALLY HARDCODED
虽然硬编码ami /子网工作,你能想到一个解决方案让我避免ami /子网的这种硬编码吗?我试着弄乱set_fact无济于事,因为我无法让它成为“region to ami”值映射的字典
2 回答
请记住
Ansible
是一个"plugable"系统,因此它比使用"native"模块找到变通方法更容易,更快 .在您的情况下,您可以轻松编写自己的自定义
lookup_plugin
,以搜索正确的subnet
.例如:
在主文件夹中创建名为
lookup_plugins
的文件夹 .创建一个名为
ansible.cfg
的文件(如果没有)在
lookup_plugins
中创建一个名为subnets.py
的文件上面的简单代码将查找给定区域中的子网 . 当然,您可以根据需要自定义它 .
然后在你的playbook中引用这个插件来找到正确的子网:
例:
在您的情况下,您可能需要引用正确的
AMI
和关联的Region
.如果您仍然希望在没有其他模块帮助的情况下执行此操作,则可以计算服务器的模数'%'和子网长度:
示例代码
瓦尔:
任务: