如何從官方 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 }}"}
就是這樣,不要忘記在測試之後刪除你的資源,或者為什麼不建立一個角色來刪除正在執行的例項:-)