ansible 如何从官方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文件:

---
- ec2_ami_find:
    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文件:

---
- ec2_vpc_subnet_facts:
    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文件:

---
- template: xx_src=my_file.txt.j2 dest=/etc/my_file.txt

然后移到您角色内的模板文件夹中:

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文件:

---
- ec2_ami:
    instance_id: "{{ instance_id }}"
    wait: yes
    name: Base_Image

现在,我认为您一直想知道如何协调所有这些角色。我对吗?如果是这样,请继续阅读。

我们将编写一个剧本,该剧本由三个剧本组成:第一个剧本适用于localhost我们的前两个角色,第二个剧本适用于just_created组。最后的角色适用于localhost。为什么localhost呢 当我们要管理一些AWS资源时,我们使用本地机器就这么简单。接下来,我们将使用瓦尔文件中,我们将会把我们的变量:ansible_key,aws_region,等...

在项目顶部创建基础结构文件夹,并在其中添加一个名为的文件aws.yml:

---
aws_region: ap-southeast-2
ansible_key: ansible
instance_type: t2.small

因此,在项目的顶部创建build_base_image.yml并添加以下内容:

---
   - hosts: localhost
     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 }}"}

就是这样,测试完成后不要忘记删除您的资源,或者为什么不创建一个角色来删除正在运行的实例:-)