如何从官方 Amazon AMI 启动 EC2 实例修改它并将其存储为新的 AMI
使用 Ansible 配置 AWS EC2 实例时,这是一个非常常见的工作流程。本文假定你对 Ansible 有基本的了解,最重要的是,假设你已正确配置它以连接到 AWS。
正如 Ansible 官方文档所坚持的那样 ,我们将使用四个角色:
1- ami_find 获取我们将启动 EC2 实例的 ami id。
2- ec2_ami_creation 有效启动 EC2 实例。
3- code_deploy 用于修改实例; 这可能是任何事情,所以我们只需将文件传输到目标机器。
4- build_ami 基于运行的 ec2 实例构建我们的新映像。这篇文章假设你处于 Ansible 项目的最高级别:my_ansible_project
第一个角色: ami_find
cd my_ansible_project/roles && ansible-galaxy init ami_find
在这个角色中我们将使用 ec2_ami_find 模块,作为一个例子,我们将搜索一个 Ubuntu 机器并获得它的 ami_id (ami-xxxxxxxx)。现在编辑 my_ansible_project/roles/ami_find/tasks/main.yml
文件:
name: "ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"
sort: name
sort_order: descending
sort_end: 1
region: "{{ aws_region }}"
register: ami_find
- set_fact: ami_ubuntu="{{ ami_find.results[0].ami_id }}"
第二个角色: ec2_ami_creation
在这里,我们将使用我们从第一个角色获得的 ami_id
,然后基于它启动我们的新实例:
cd my_ansible_project/roles && ansible-galaxy init ec2_ami_creation
在这个角色中,我们将使用最重要的 ec2_module 来启动我们的实例。现在编辑 my_ansible_project/roles/ec2_ami_creation/tasks/main.yml
文件:
region: "{{aws_region}}"
register: vpc
- name: creation of security group of the ec2 instance
ec2_group:
name: example
description: an example EC2 group
region: "{{ aws_region }}"
rules:
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
state: present
register: ec2_sg
- name: create instance using Ansible
ec2:
key_name: "{{ ansible_key }}"
group: example
vpc_subnet_id: "{{vpc.subnets[0].id}}"
instance_type: "{{ instance_type }}"
ec2_region: "{{ aws_region }}"
image: "{{ base_image }}"
assign_public_ip: yes
wait: yes
register: ec2
- set_fact: id={{ec2.instances[0].id}}
- name: adding the newly created instance to a temporary group in order to access it later from another play
add_host: name={{ item.public_ip }} groups=just_created
with_items: ec2.instances
- name: Wait for SSH to come up
wait_for: host={{ item.public_dns_name }} port=22 delay=10 timeout=640 state=started
with_items: ec2.instances
第三个角色: code_deploy
在这里,我们将配置此实例,该实例已添加到名为 just_created
的组中
cd my_ansible_project/roles && ansible-galaxy init code_deploy
在此角色中,我们将使用 template_module 传输文件并在其中写入计算机主机名。现在编辑 my_ansible_project/roles/code_deploy/tasks/main.yml
文件:
然后移动到角色内的模板文件夹:
cd my_ansible_project/roles/templates
并添加一个名为 my_file.txt.j2
的文件,其中包含:
my name is {{ ansible_hostname }}`
第四个角色: build_ami
我们现在将使用 ec2_ami 模块创建正在运行的实例的映像 。移动到你的项目文件夹并:
cd my_ansible_project/roles && ansible-galaxy init build_ami
现在编辑 my_ansible_project/roles/build_ami/tasks/main.yml
文件:
instance_id: "{{ instance_id }}"
wait: yes
name: Base_Image
现在,我想你一直想知道如何协调所有这些角色。我对吗?如果是这样,继续阅读。
我们将编写一个由三个剧本组成的剧本:第一部适用于 localhost
将调用我们的前两个角色,第二部分适用于我们的 just_created 组。最后一个角色将适用于 localhost
。为什么 localhost
?当我们想要管理一些 AWS 资源时,我们使用本地机器,就这么简单。接下来,我们将使用一个 vars 文件,我们将在其中放入变量:ansible_key
,aws_region
等…
在项目顶部创建基础架构文件夹,并在其中添加一个名为 aws.yml
的文件:
ansible_key: ansible
instance_type: t2.small
所以在项目的顶部创建 build_base_image.yml
并添加:
connection: local
gather_facts: False
vars_files:
- infrastructure/aws.yml
roles:
- ami_find
- { role: ec2_creation, base_image: "{{ ami_ubuntu }}"}
- hosts: just_created
connection: ssh
gather_facts: True
become: yes
become_method: sudo
roles:
- code_deploy
- hosts: localhost
connection: local
gather_facts: False
vars_files:
- infrastructure/aws.yml
roles:
- { role: new_image, instance_id: "{{ id }}"}
就是这样,不要忘记在测试之后删除你的资源,或者为什么不创建一个角色来删除正在运行的实例:-)