前文 通过 ansible 创建 openstack 虚拟机并部署应用(配置篇)
接下来我们实战一下。
目录结构
── ansible.cfg
├── group_vars
│ ├── all.yml
├── openstack.py
├── README.md
├── roles
│ ├── newtouch.MySQL
│ ├── newtouch.SystemConfig
│ ├── newtouch.UpdateRootPass
│ └── openstack.CreateServer
├── setup_mysql.yml
group_vars/all.yml 里需要设置
ansible_user: root
ansible_ssh_pass: xxxxxxxxxxx
前提是 openstack 集群里的虚拟机镜像,root 密码相同。
默认值配置文件 roles/openstack.CreateServer/defaults/main.yml
role 的默认值,根据实际情况,填入相关信息。以 vm_ 开头的变量是为了测试用,预设的。
auth:
auth_url: http://192.168.205.2:5000/v2.0
username: admin
password: xxxxxxxxxxxxxxxxxx
project_name: Haibin_Lee
# image_id
ubuntu_14_disk_50_v2: 5c67bf65-f699-49e8-955a-72152fb690f4
centos7_50_v2: f9391999-373b-4f0d-9c76-07c19e4e86e5
flavor:
- {name: 1CPU_1G, id: e3aff42c-f260-4dea-ada5-1241b5853652}
- {name: 2CPU_4G, id: 45b099ac-4ae4-4526-a6e2-f34cc2934e1b}
vm_state: present
vm_name: db1
vm_image: '{{ ubuntu_14_disk_50_v2 }}'
vm_key: lihaibin
vm_flavor: 1CPU_1G
vm_network: public
vm_group: poc
任务代码 roles/openstack.CreateServer/tasks/main.yml
- block:
- name: Set the new instance's name
debug:
msg: "The new instance's name is {{ vm_name }}-{{ ansible_date_time.epoch }}"
- name: Creating new instance
os_server:
state: '{{ vm_state }}'
auth:
auth_url: '{{ auth.auth_url }}'
username: '{{ auth.username }}'
password: '{{ auth.password }}'
project_name: '{{ auth.project_name }}'
name: "{{ vm_name }}-{{ ansible_date_time.epoch }}"
image: '{{ vm_image }}'
flavor: '{{ vm_flavor }}'
network: '{{ vm_network }}'
meta:
hostname: "{{ vm_name }}-{{ ansible_date_time.epoch }}"
- name: Gathering the new instance's facts
os_server_facts:
auth:
auth_url: '{{ auth.auth_url }}'
username: '{{ auth.username }}'
password: '{{ auth.password }}'
project_name: '{{ auth.project_name }}'
server: "{{ vm_name }}-{{ ansible_date_time.epoch }}"
- name: Get the new instance's IP address
block:
- set_fact:
vm_ip: "{{ openstack_servers[0]['accessIPv4'] }}"
- debug:
msg: "The new instance's IP address is {{ vm_ip }}"
- name: Waiting for the new instance up and run
wait_for:
host: '{{ vm_ip }}'
port: 22
search_regex: OpenSSH
sleep: 10
timeout: 3000
- name: Add the new instance into inventory
add_host:
name: "{{ vm_name }}-{{ ansible_date_time.epoch }}"
ansible_host: "{{ vm_ip }}"
rescue:
- name: Remove the new instance when failed
os_server:
state: absent
auth:
auth_url: '{{ auth.auth_url }}'
username: '{{ auth.username }}'
password: '{{ auth.password }}'
project_name: '{{ auth.project_name }}'
name: "{{ vm_name }}-{{ ansible_date_time.epoch }}"
这里我使用了 {{ vm_name }}-{{ ansible_date_time.epoch }}
作为新机器的名称,这样可以避免名称重复。如果创建过程中遇到任何失败,会执行删除虚拟机的操作,避免产生垃圾资源。
剧本 setup_mysql.yml
这个剧本的重点在于 post_tasks 里
- 在新虚拟机创建完成之后,我们还是要通过 openstack-connector 作为跳板机来访问新虚拟机,这样才能保证
{{ vm_name }}-{{ ansible_date_time.epoch }}
这个值是可以被读取到的。 - 基于这个模板,在 post_tasks 里,include_role 部分可以随意发挥,把你要执行的 role 加进来。这样你可以做到一键创建虚拟机并部署应用到虚拟机。
- 最后我们通过 openstack-connector 里的 sendmail,发出一封邮件,包含机器的相关信息。
- hosts: openstack-connector
vars:
new_password: newtouch
mysql_user: root
mysql_password: newtouch
bind_address: 0.0.0.0
max_connections: 256
innodb_buffer_pool_size: "{{ (ansible_memtotal_mb * 0.5) | round | int }}M"
owner_email: "haibin.li@newtouch.cn"
roles:
- openstack.CreateServer
post_tasks:
- block:
- include_role:
name: newtouch.SystemConfig
- include_role:
name: newtouch.MySQL
- include_role:
name: newtouch.UpdateRootPass
delegate_to: "{{ vm_name }}-{{ ansible_date_time.epoch }}"
delegate_facts: True
- name: Send mail with instance info
mail:
host: localhost
from: 'ansible@newtouch.com>'
to: '{{ owner_email }}'
subject: "Server {{ vm_name | upper }}-{{ ansible_date_time.epoch }} has been successfully created."
body: |
The server {{ vm_name | upper }}-{{ ansible_date_time.epoch }} info:
- IP: {{ vm_ip }}
- SYSTEM USER: root
- SYSTEM PASS: {{ new_password }}
- MYSQL USER: {{ mysql_user }}
- MYSQL PASS: {{ mysql_password }}
Please keep this email safe.
charset: utf8
本剧本在 Ansible Tower 里也通过测试
我们通过问卷方式获取需要的变量值,一个简单的数据库虚拟机就可以实现一键创建了。开发人员再也不用等待运维人员的协助。