如何配置自动化工具-Ansible?



什么是Ansible?

Ansible是一个开源软件工具,可实现自动执行软件安装及配置,配置管理和应用程序部署。

Ansible的优点

无代理

客户端上没有要与服务器通信的软件或代理。直接通过SSH机制连接服务器

重复部署

无论你调用该操作多少次,结果都是一样的。

简单且可扩展

Ansible是用Python编写的,并将YAML用于编写playbook,这两门语言都被认为是相对其他开发语言最容易学习和入门的。

Ansible安装配置

#Ubuntu/Debian
sudo apt-get install ansible
# CentOS
sudo yum install ansible
#Mac-OS
brew install ansible

Ansible架构和组件

模块(Modules)

在服务器上执行程序安装,例如,

一般是运行此命令,手动安装:

sudo apt-get install htop

而我们可以通过使用apt模块来安装htop

- name:Install htop
apt:name = htop

使用模块可以让你知道是否已安装。

插件(Plugins)

插件是增强Ansible的核心功能。Ansible自带了很多非常方便的插件,你可以很轻松的编写自己的插件。

主机列表(Host Inventories)

要提供主机列表,我们需要提供 inventory 。这是配置主机文件的方式。

以最简单的方式,我们的主机文件可以包含以下这一行:

35.178.45.231 ansible_ssh_user = ubuntu
剧本(Playbook)

Ansible playbook是一种以脚本方式将命令发送到远程服务器的方法。你可以通过将脚本传递到一个或多个服务器来配置整个复杂的环境,而不必单独使用Ansible命令经过命令行远程配置服务器。

组变量(group_vars)

该文件包含一组或多组变量,例如db用户名和密码。

db_user: ubuntu


db_password: 123456
角色(roles)

roles是将多个tasks合并一起执行的方式,可以通过干净清晰的目录结构以非常有效的方式进行自动化,也有利于配置管理

处理者(handlers)

handlers是tasks的列表,与常规tasks没有什么实质的不同,它们由全局唯一名称引用,并由通知程序通知。如果没有任何通知处理程序,它将不会运行。无论有多少个tasks通知handlers,在特定playbook中完成所有tasks后,它将仅运行一次。

Tags

如果有大型playbook,则可以在不运行整个playbook的情况下运行特定部分的配置可能会很有用。增加了很大的灵活性。

实例:安装程序,运行的步骤

构建主机和ansible.cfg在Ansible中定义Roles在Ansible中定义Handlers安装PHP模块安装Nginx添加Nginx默认配置文件添加vars以管理变量创建MySql数据库,用户名和密码创建playbook执行playbook安装部署构建主机和ansible.cfg

hosts.ini

[test]
#your instance IP
127.0.0.39

ansible.cfg

[defaults]
hostfile = hosts.ini
# configure log dir
log_path= logs/ansible-log.log
在Ansible中定义Roles

使用Ping模块来验证主机是否正常工作,然后我将更新所有软件包并安装两个模块git和htop

---
- ping: ~
###
- name: Update apt packages
apt:
update_cache: yes
##
- name: Install GIT VCS
apt:
name: git
state: latest
##
- name: Install htop


apt: name=htop
在Ansible中定义Handlers

---
- name: Restart PHP-FPM
service:
name: php{{php_version}}-fpm
state: restarted
####
- name: Restart Nginx
service:
name: nginx
state: restarted
安装Php模块 要在ansible中触发handlers,我们必须使用notify:重新启动PHP-FPM,handlers名称应该是唯一的,例如,如果您想仅从playbook中运行此任务,则只能通过使用 --tags =“ php”运行命令,它将仅执行此任务

---
- name: Install PHP {{php_version}} PPA Repo
apt_repository:
repo: 'ppa:ondrej/php'
tags:
- php
##
- name: Install PHP {{php_version}}
apt: name=php{{php_version}} state=latest
##
- name: Install PHP packages
become: true
apt:
name: "{{ item }}"
state: latest
with_items:
- php{{php_version}}-curl
- php{{php_version}}-fpm
- php{{php_version}}-intl
- php{{php_version}}-mysql
- php{{php_version}}-xml
- php{{php_version}}-mbstring
notify: Restart PHP-FPM
tags:
- php
安装Nginx模块

- name: Install Nginx web server
apt:
name: nginx
state: latest
notify: Restart Nginx
tags:
- nginx
###
- name: Update nginx config files
become: true
template:
src: templates/nginx.conf
dest: "/etc/nginx/sites-available/default"
tags:
- nginx
notify: Restart Nginx
###
- name: link nginx config
become: true
file:
src: "/etc/nginx/sites-available/default"
dest: "/etc/nginx/sites-enabled/default"
state: link
tags:
- nginx
notify: Restart Nginx
添加nginx默认配置文件

server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
\t\tserver_name {{ server_name }};
root {{ app_work_dir }}public;
location / {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
}
if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location ~ \\.php$ {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;


fastcgi_pass unix:/var/run/php/php{{php_version}}-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME {{app_work_dir}}public$fastcgi_script_name;
fastcgi_param APPLICATION_ENV testing;
fastcgi_param PATH /usr/bin:/bin:/usr/sbin:/sbin;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
添加vars以管理变量

vars.yml

注:可以使用ansible-vault加密和解密vars

---
##@ref https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#variables-and-vaults
ansible_ssh_user: "ubuntu"
current_user: "ubuntu"
server_name: "app_name"
repo_git_url: "app_github_url"
ansible_ssh_private_key_file: "ssh_dir"
php_version: 7.2
app_work_dir: /var/www/app_name/
#mysql config
mysql_host: "mysql_host"
mysql_db: app_name
mysql_user: sql_user
mysql_pass: sql_pass
#other config
cache_driver: file
session_driver: file
app_env: production
app_debug: false
app_key: "your_app_key"
app_name: "app_name"
app_url: "your_app_url"
创建MySql数据库,用户名和密码

- mysql_user:
name: "{{mysql_user}}"
password: "{{mysql_pass}}"
priv: '*.*:ALL'


state: present
tags:
- mysql-db
##
- name: Create APP DB database
mysql_db: name="{{mysql_db}}" state=present login_user="{{mysql_user}}" login_password="{{mysql_pass}}"
创建playbook

将test定义为该playbook的主机,而sudo yes则使您能够以sudo用户身份执行命令,我们有vars_files存储我们的vars,我们有一组roles,每个role执行特定task,最后有handlers引入所有项目的handler

---
- hosts: test
#common options between modules
sudo: yes
gather_facts: no
vars_files:
- ./group_vars/vars.yml
roles:
- misc
- php
- mysql
- redis
- nginx
- bootstrap-app
- code-deploy
###
handlers:
- include: handlers/main.yml
执行playbook安装部署

#ansible-playbook playbookName
ansible-playbook code-deploy.yml# run with specific tags
ansible-playbook playbook.yml --tags="env-files,php"
完整的目录结构

├── ansible.cfg
├── code-deploy.yml
├── files
│ └── dump.sql
├── group_vars
│ └── vars.yml
├── handlers


│ └── main.yml
├── hosts.ini
├── logs
│ └── ansible-log.log
├── roles
│ ├── bootstrap-app
│ │ └── tasks
│ │ └── main.yml
│ ├── code-deploy
│ │ ├── tasks
│ │ │ ├── config-files.yml
│ │ │ └── main.yml
│ │ └── templates
│ │ └── env.conf
│ ├── misc
│ │ └── tasks
│ │ └── main.yml
│ ├── mysql
│ │ └── tasks
│ │ ├── config.yml
│ │ └── main.yml
│ ├── nginx
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ └── nginx.conf
│ ├── php
│ │ └── tasks
│ │ └── main.yml
│ └── redis
│ └── tasks
│ └── main.yml
├──/>│ ├── install_composer.sh
│ └── startup.sh
└── site.yml

参考文献

https://ansible-tran.readthedocs.io/en/latest/