非常好的Ansible入门教程(超简单)-程序员宅基地

技术标签: ubuntu  linux  服务器  ansible  


Ansible是一个配置管理和配置工具,类似于Chef,Puppet或Salt。这是一款很简单也很容易入门的部署工具,它使用SSH连接到服务器并运行配置好的任务,服务器上不用安装任何多余的软件,只需要开启ssh,所有工作都交给client端的ansible负责。
关于Ansible的一个好处是,将bash脚本转换为可执行任务是非常容易的。我们可以编写自己的配置程序,但是Ansible更加干净,因为它可以自动在执行任务之前获取上下文。ansible任务是幂等的,没有大量额外的编码,ansible可以一次又一次地安全运,而bash命令这种幂等性。
ansible使用“facts”来确保任务的幂等安全运行, 它是在运行任务之前收集的系统和环境信息。ansible使用这些facts来检查状态,看看是否需要改变某些东西以获得所需的结果。这使得ansible可以让服务器一次又一次地运行可复制的任务。

1 安装

当然我们需要先安装Ansible。任务可以从任何可安装的机器上运行。

1.1 Ubuntu

在Ubuntu 16.04上安装Ansible的方法。

sudo apt-get install -y ansible

apt-get安装的ansible版本很低,建议使用pip方式安装

sudo pip install ansible

2 配置

ansible的默认配置文件路径为 /etc/ansible,然而,一个常见的用途是将其安装在一个virtualenv中,在这种情况下,我们一般不会使用这些默认文件。我们可以根据需要在本地目录中创建配置文件。

2.1 管理服务器:Inventory文件

您可以创建一个inventory文件,用于定义将要管理的服务器。这个文件可以命名为任何名字,但我们通常会命名为hosts或者项目的名称。
在hosts文件中,我们可以定义一些要管理的服务器。这里我们将定义我们可能要在“web”标签下管理的两个服务器。标签是任意的。

[web]
192.168.22.10
192.168.22.11

现在已经够好了,如果需要,我们可以定义主机范围,多个组,可重用变量,并使用其他花哨的设置,包括创建动态的inventory。
当我们在本地机器运行ansible时,我们不需要关心inventory文件中的内容,我将告诉您在本地和远程服务器上运行ansible。现在,让我们将hosts文件设置为指向本地主机local和remote虚拟远程主机。
hosts文件:

[local]
127.0.0.1

[remote]
192.168.1.2

与本地主机和远程服务器连接的命令。

2.2 基础:运行命令

我们开始对服务器运行任务。ansible会假定你的服务器具有SSH访问权限,通常基于SSH-Key。因为Ansible使用SSH,所以它需要能够SSH连接到服务器。但是,ansible将尝试以正在运行的当前用户身份进行连接。如果我正在运行ansible的用户是ubuntu,它将尝试以ubuntu连接其他服务器。

# Run against localhost
$ ansible -i ./hosts --connection=local local -m ping

# Run against remote server
$ ansible -i ./hosts remote -m ping
127.0.0.1 | success >> {
    "changed": false,
    "ping": "pong"
}

如果你是在cygwin下运行,遇到了“Failed to connect to the host via ssh: mux_client_request_session: read from master failed”的错误,可以执行:

ansible -i ./hosts remote -v -m ping -u root --private-key=~/.ssh/id_rsa

使用–connection=local告诉ansible不尝试通过SSH运行命令,因为我们只是影响本地主机。但是,我们仍然需要一个hosts文件,告诉我们连接到哪里。
在任何情况下,我们可以看到从ansible得到的输出是一些JSON,它告诉我们Task(我们对ping模块的调用)是否进行了任何更改和结果。

命令说明:

-i ./hosts - 设置库存文件,命名为 hosts
remote,local,all-使用这个标签的下定义的服务器hosts清单文件。“all”是针对文件中定义的每个服务器运行的特殊关键字
-m ping- 使用“ping”模块,它只是运行ping命令并返回结果
-c local| --connection=local - 在本地服务器上运行命令,而不是SSH

一些常用命令:
-i PATH --inventory=PATH 指定host文件的路径,默认是在/etc/ansible/hosts
--private-key=PRIVATE_KEY_FILE_PATH 使用指定路径的秘钥建立认证连接
-m DIRECTORY --module-path=DIRECTORY 指定module的目录来加载module,默认是/usr/share/ansible
-c CONNECTION --connection=CONNECTION 指定建立连接的类型,一般有ssh ,local

2.2.1 模块(Modules)

ansible使用“模块”来完成大部分的任务。模块可以做安装软件,复制文件,使用模板等等。

模块是使用Ansible 的方法

因为它们可以使用可用的上下文(“Facts”),以便确定要完成任务需要做什么操作。
如果我们没有模块,我们将运行任意的shell命令,我们也可以使用bash脚本。这是一个任意shell命令看起来像在Ansible(它使用的shell模块!):

# Run against a local server
ansible -i ./hosts local --connection=local -b --become-user=root \
    -m shell -a 'apt-get install nginx'

# Run against a remote server
ansible -i ./hosts remote -b --become-user=root all \
    -m shell -a 'apt-get install nginx'

这里,sudo apt-get install nginx命令将使用“shell”模块运行。
命令说明:

-b - “成为”,在运行命令时告诉可以成为另一个用户。
--become-user=root - 以用户“root”运行以下命令(例如,使用命令使用“sudo”)。我们可以在此定义任何现有的用户。
-a 用于将任何参数传递给定义的模块 -m

但是这并不是特别强大。尽管能够一次在所有服务器上运行这些命令,但是我们仍然只能完成任何bash脚本可能执行的操作。如果我们使用了更合适的模块,我们可以运行命令来保证结果。可靠的模块确保我们可以一次又一次地运行相同的任务,而不会影响最终结果。
要在Debian / Ubuntu服务器上安装软件,“apt”模块将运行相同的命令,但确保幂等。

# Run against a local server
ansible -i ./hosts local --connection=local -b --become-user=root \
    -m apt -a 'name=nginx state=installed update_cache=true'

127.0.0.1 | success >> {
    "changed": false
}

# Run against a remote server
ansible -i ./hosts remote -b --become-user=root \
    -m apt -a 'name=nginx state=installed update_cache=true'

127.0.0.1 | success >> {
    "changed": false
}

or:
ansible -i ./hosts remote -v -m apt -a 'name=nginx state=installed update_cache=true' -u test -s -K --private-key=~/.ssh/id_rsa

这将使用apt模块来更新存储库缓存并安装Nginx(如果没有安装)。
运行任务的结果是"changed": false。这表明没有变化; 我已经使用该shell模块安装了Nginx 。好的是,我可以一遍又一遍地运行这个命令,而不用担心它会改变预期的结果 - Nginx已经安装,Ansible知道,并且不尝试重新安装它。
命令说明:

-i ./hosts - 设置inventory文件,命名为 hosts
-b - “成”,告诉可以成为另一个用户来运行命令
--become-user=root - 以用户“root”运行以下命令(例如,使用“sudo”命令)
local| remote - 从库存文件中的本地或远程定义的主机上运行
-m apt- 使用apt模块
-a 'name=nginx state=installed update_cache=true' - 提供apt模块的参数,包括软件包名称,所需的结束状态以及是否更新软件包存储库缓存

常用命令:
-u USERNAME --user=USERNAME 指定移动端的执行用户
-U SUDO_USERNAME --sudo-user=USERNAME
-s --sudo -u指定用户的时候,使用sudo获得root权限
-k --ask-pass  提示输入ssh的密码,而不是使用基于ssh的密钥认证
-K --ask-sudo-pass 提示输入sudo密码,与--sudo一起使用

我们可以通过这种特殊方式运行我们所需要的所有任务(通过模块),但是让我们来做这个更具管理性。我们将把这个任务移动到一个Playbook中,它可以运行和协调多个Tasks。

2.3 剧本(Playbooks)

Playbook可以运行多个任务,并提供一些更高级的功能。让我们将上述任务移到一本剧本中。在ansible中剧本(playbooks)和角色(roles)都使用Yaml文件定义。
创建文件nginx.yml:

---
# hosts could have been "remote" or "all" as well
- hosts: local
  connection: local
  become: yes
  become_user: root
  tasks:
   - name: Install Nginx
     apt:
       name: nginx
       state: installed
       update_cache: true

此任务与我们的ad-hoc命令完全相同,包括设置本地连接的使用。
这将使用inventory文件中[local]标签下的服务器hosts。
如果我们没有使用本地连接,我们会这样做:

---
- hosts: remote
  become: yes
  become_user: root
  tasks:
   - name: Install Nginx
     apt:
       name: nginx
       state: installed
       update_cache: true

这将使用inventory文件中[remote]标签下的服务器hosts。

在我们的Tasks文件中使用become并become_user再次使用Ansible来sudo以root用户身份运行命令,然后传递Playbook文件。

使用一个yaml playbook文件,我们需要使用这个ansible-playbook命令,现在就更容易运行:

$ ansible-playbook -i ./hosts nginx.yml

PLAY [local] ******************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [Install Nginx] *********************************************************
ok: [127.0.0.1]

PLAY RECAP ********************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0

我们在运行过程中获得了一些有用的反馈,包括“可执行任务”运行及其结果。在这里我们看到所有运行都OK,但没有改变。我已经安装了Nginx

2.3.1 处理程序(Handlers)

处理程序与任务完全相同(它可以做task可以做的任何事),但只有当另一个任务调用它时才会运行。您可以将其视为事件系统的一部分; 处理程序将通过其侦听的事件调用进行操作。
这对于运行任务后可能需要的“辅助”操作非常有用,例如在配置更改后安装或重新加载服务后启动新服务。

---
# Example shows using the local machine still
# Remove 'connection' and set hosts to 'remote' for a remote connection
- hosts: local
  connection: local
  become: yes
  become_user: root
  tasks:
   - name: Install Nginx
     apt:
       name: nginx
       state: installed
       update_cache: true
     notify:
      - Start Nginx

  handlers:
   - name: Start Nginx
     service:
       name: nginx
       state: started

这里我们添加一个notify指令到安装任务。这将在任务运行后通知名为“Start Nginx”的处理程序。

然后我们可以创建名为“Start Nginx”的处理程序。此处理程序是通知“Start Nginx”时调用的任务。
这个特定的处理程序使用服务模块,它可以启动,停止,重启,重新加载(等等)系统服务。在这种情况下,我们告诉Ansible,我们要启动Nginx。
让我们再次运行这本Playbook:

$ ansible-playbook -i ./hosts nginx.yml

PLAY [local] ******************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [Install Nginx] *********************************************************
ok: [127.0.0.1]

NOTIFIED: [nginx | Start Nginx] ***********************************************
ok: [127.0.0.1]

PLAY RECAP ********************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0

我们得到类似的输出,但是这次Handler是运行的。
通知程序只在运行任务时运行。

Note:如果我已经安装了Nginx,则安装Nginx任务将不会运行,通知程序也将不会被调用。

我们可以使用Playbook来运行多个任务,添加变量,定义其他设置,甚至包括其他的剧本。

2.3.2 更多的任务(More Tasks)

接下来,我们可以为此Playbook添加更多的任务,并探索其他一些功能。

---
# Example shows using the local machine still
# Remove 'connection' and set hosts to 'remote' for a remote connection
- hosts: local
  connection: local
  become: yes
  become_user: root
  vars:
   - docroot: /var/www/serversforhackers.com/public
  tasks:
   - name: Add Nginx Repository
     apt_repository:
       repo: ppa:nginx/stable
       state: present
     register: ppastable

   - name: Install Nginx
     apt:
       pkg: nginx
       state: installed
       update_cache: true
     when: ppastable|success
     notify:
      - Start Nginx

   - name: Create Web Root
     file:
      path: '{
   { docroot }}'
      mode: 775
      state: directory
      owner: www-data
      group: www-data
     notify:
      - Reload Nginx

  handlers:
   - name: Start Nginx
     service:
       name: nginx
       state: started

    - name: Reload Nginx
      service:
        name: nginx
        state: reloaded

现在有三个任务:

Add Nginx Repository- 使用apt_repository模块添加Nginx稳定PPA以获取最新的稳定版本的Nginx 。
Install Nginx - 使用Apt模块安装Nginx。
Create Web Root - 最后创建一个Web根目录。

新的register和when指令,可以实现在某些事情发生后让ansible执行任务的功能。

Note: 您还可以注册模块操作的结果,并使用定义的变量根据注册(register)的变量值有条件(when)地执行操作。例如,注册通过shell模块运行命令的结果可以让您访问该命令的stdout。

同时还使用了一个变量。docroot变量在定义vars部分。然后将其用作创建定义目录的文件模块的目标参数。

需要注意的是,path配置使用括号{ { var-name }},这是Jinja2的模板。为了使Ansible能够在括号内解析Jinja2模板变量,该行必须是单引号或双引号 - 例如,path: '{ { docroot }}'而不是path: { { docroot }}。不使用引号将导致错误。
这个playbook可以用通常的命令运行:

ansible-playbook -i ./hosts nginx.yml

所以,我们已经运行了一些ad-hoc命令,使用了可复制的模块,并将一些相关任务组织到一个手册中。

接下来,我们将通过将Playbook组织成一个角色进一步获得可靠性,这有助于我们组织相关项目,如文件和模板,同时还帮助我们组织更复杂的相关任务和操作。

2.4 角色(roles)

角色很适合组织多个相关任务并封装完成这些任务所需的数据。例如,安装Nginx可能涉及添加软件包存储库,安装软件包和设置配置。
此外,真实的配置通常需要额外的数据,如变量,文件,动态模板等等。这些工具可以与Playbook一起使用,但是我们可以通过将相关任务和数据组织成一个角色(role, 相关的结构)很快就能做得更好。
角色有一个这样的目录结构:

roles
  rolename
   - files
   - handlers
   - meta
   - templates
   - tasks
   - vars

在每个子目录中(eg: files,handlers等等),Ansible将自动搜索并读取叫做main.yml的yaml文件。
接下来我们将分解nginx.yml文件内容为不同的组件,并将每个组件放在相应的目录中,以创建一个更干净,更完整的配置工具集。

2.4.1 创建角色(Creating a Role)

我们可以使用ansible-galaxy命令来创建一个新角色。此工具可用于将角色保存到Ansible的公共注册表,但是我通常只是使用它来在本地创建role的基础目录结构。

我们来看看如何设置:

# Head to our previously created directory
cd ~/ansible-example

# In case we left our virtualenv at some point 
source .venv/bin/activate

# Create a roles directory
mkdir roles
cd roles

# Bootstrap a new role named "nginx"
ansible-galaxy init nginx

目录名称roles是一种惯例,在运行一个playbook时可以用来查找角色。该目录应该始终被命名roles,但并不强制。在roles目录中运行 ansible-galaxy init nginx 命令将创建新角色所需的目录和文件。

我们来看看我们新建的nginx角色的每个部分~/ansible-example/roles/nginx。

2.4.2 文件(files)

首先,在files目录中,我们可以添加我们要复制到我们的服务器中的文件。对于nginx,我经常复制H5BP的Nginx组件配置。我只需从Github下载最新的信息,进行一些调整,并将它们放入files目录中。

~/ansible-example
 - roles
 - - nginx
 - - - files
 - - - - h5bp

我们稍后会看到,H5BP配置文件将通过复制模块添加到服务器。

2.4.3 处理程序(handlers)

我们可以把曾经在nginx.yml 剧本中的定义的所有处理程序放入到handlers目录中。约定必须包含main.yml文件。

handlers/main.yml 内容:

---
- name: Start Nginx
  service:
    name: nginx
    state: started

- name: Reload Nginx
  service:
    name: nginx
    state: reloaded

一旦handlers/main.yml中的处理程序定义好了,我们可以自由地从其他的yaml配置中引用它们。

2.4.4 元(meta)

meta目录中的main.yml文件包含Role元数据,包含的依赖关系。如果这个角色依赖于另一个角色,我们可以在这里定义。例如,nginx角色取决于安装SSL证书的ssl角色。约定必须包含main.yml文件。
meta/main.yml 内容:

---
dependencies:
  - { role: ssl }

如果我调用了“nginx”角色,它将尝试首先运行“ssl”角色。
否则我们可以省略此文件,或将角色定义为没有依赖关系:

---
dependencies: []

2.4.5 模板(templates)

基于Python的Jinja2模板引擎(和django的模板引擎很类似),模板文件可以包含模板变量。这里的文件应该以.j2为类型后缀(eg.uwsgi.j2),提倡但是不强制,也可以取其他的名字。类似于files,在templates目录中没有main.yml文件,只包含.j2后缀的模板文件。
这是一个Nginx服务器(“虚拟主机”)配置的例子。请注意,它使用了稍后在vars/main.yml文件中定义的一些变量。
我们的示例中的Nginx配置文件位于templates/serversforhackers.com.conf.j2:

server {
    # Enforce the use of HTTPS
    listen 80 default_server;
    server_name {
   { domain }};
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl default_server;

    root /var/www/{
   { domain }}/public;
    index index.html index.htm index.php;

    access_log /var/log/nginx/{
   { domain }}.log;
    error_log  /var/log/nginx/{
   { domain }}-error.log error;

    server_name {
   { domain }};

    charset utf-8;

    include h5bp/basic.conf;

    ssl_certificate           {
   { ssl_crt }};
    ssl_certificate_key       {
   { ssl_key }};
    include h5bp/directive-only/ssl.conf;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt  { log_not_found off; access_log off; }

    location ~ \.php$ {
        include snippets/fastcgi.conf;
        fastcgi_pass unix:/var/run/php7.1-fpm.sock;
    }
}

这是一个相当标准的用于PHP应用程序的Nginx配置。这里有三个变量:


ssl_crt
ssl_key
这三个变量将在变量部分(vars)中定义。

2.4.6 变量(vars)

在使用任务集成所有事情之前,让我们来看看变量。该vars目录包含一个main.yml文件(如handlers和meta目录一样),在main.yml中我们可以列出将要使用的所有变量。
以下是该vars/main.yml文件的内容:

---
domain: serversforhackers.com
ssl_key: /etc/ssl/sfh/sfh.key
ssl_crt: /etc/ssl/sfh/sfh.crt

我们可以在这个角色的其他地方使用这三个变量。我们在上面的模板中看到它们的使用,但是我们也可以在我们定义的任务中看到它们。

Note:如果您有敏感信息添加到变量文件中,则可以使用ansible-vault加密文件,下面将对此进行说明。

2.4.7 任务(tasks)

终于到了将一切都是放在一系列的任务中的时候了。
使用角色时运行的主文件是tasks/main.yml文件。看看我们的用例将会是什么样的:

---
- name: Add Nginx Repository
  apt_repository:
    repo: ppa:nginx/stable
    state: present

- name: Install Nginx
  apt:
    pkg: nginx
    state: installed
    update_cache: true
  notify:
    - Start Nginx

- name: Add H5BP Config
  copy:
    src: h5bp
    dest: /etc/nginx
    owner: root
    group: root

- name: Disable Default Site Configuration
  file:
    dest: /etc/nginx/sites-enabled/default
    state: absent

# `dest` in quotes as a variable is used!
- name: Add SFH Site Config
  register: sfhconfig
  template:
    src: serversforhackers.com.j2
    dest: '/etc/nginx/sites-available/{
   { domain }}.conf' 
    owner: root
    group: root

# `src`/`dest` in quotes as a variable is used!
- name: Enable SFH Site Config
  file:
    src: '/etc/nginx/sites-available/{
   { domain }}.conf'
    dest: '/etc/nginx/sites-enabled/{
   { domain }}.conf'
    state: link

# `dest` in quotes as a variable is used!
- name: Create Web root
  file:
    dest: '/var/www/{
   { domain }}/public'
    mode: 775
    state: directory
    owner: www-data
    group: www-data
  notify:
    - Reload Nginx

# `dest` in quotes as a variable is used!
- name: Web Root Permissions
  file:
   dest: '/var/www/{
   { domain }}'
   mode: 775
   state: directory
   owner: www-data
   group: www-data
   recurse: yes
  notify:
    - Reload Nginx

这一系列任务使得Nginx能被完整的安装。任务按照出现的顺序完成以下工作:

1 添加nginx / stable库
2 安装并启动Nginx
3 添加H5BP配置文件
4 从sites-enabled目录中删除文件的符号链接来禁用默认的Nginx配置
5 将serversforhackers.com.conf.j2虚拟主机模板复制到Nginx配置中,渲染模板
6 通过将其符号链接到sites-enabled目录来启用Nginx服务器配置
7 创建Web根目录
8 更改项目根目录的权限(递归),该目录位于之前创建的Web根目录之上

有一些新的模块(和一些我们已经涵盖的新用途),包括复制,模板和文件模块。通过设置每个模块的参数,我们可以做一些有趣的事情,例如确保文件“不存在”(如果存在则删除它们)的state: absent,或者通过创建一个文件作为符号链接的state: link。您应该检查每个模块的文档,以查看可以用它们完成哪些有趣和有用的事情。

2.4.8 运行角色(Running the Role)

要对服务器运行一个或多个角色,我们将重新使用另一个playbook。该playbook与roles目录位于同一个目录中,同一层级。当我们用ansible-playbook命令运行的时候需要先cd进入到该目录中。
让我们创建一个“主”的yaml文件(被ansible-playbook命令执行的文件),该文件定义要使用的角色以及运行它们的主机:
文件~/ansible-example/server.yml位于与roles目录相同的目录中:

---
# run locally here, yadda yadda yadda
- hosts: local
  connection: local
  roles:
    - nginx

所以,我们只是定义角色,而不是在本Playbook文件中定义所有的变量和任务。角色负责具体细节。

然后我们可以运行角色:

ansible-playbook -i ./hosts server.yml

以下是运行Nginx角色的Playbook文件的输出:

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [nginx | Add Nginx Repository] ******************************************
changed: [127.0.0.1]

TASK: [nginx | Install Nginx] *************************************************
changed: [127.0.0.1]

TASK: [nginx | Add H5BP Config] ***********************************************
changed: [127.0.0.1]

TASK: [nginx | Disable Default Site] ******************************************
changed: [127.0.0.1]

TASK: [nginx | Add SFH Site Config] *******************************************
changed: [127.0.0.1]

TASK: [nginx | Enable SFH Site Config] ****************************************
changed: [127.0.0.1]

TASK: [nginx | Create Web root] ***********************************************
changed: [127.0.0.1]

TASK: [nginx | Web Root Permissions] ******************************************
ok: [127.0.0.1]

NOTIFIED: [nginx | Start Nginx] ***********************************************
ok: [127.0.0.1]

NOTIFIED: [nginx | Reload Nginx] **********************************************
changed: [127.0.0.1]

PLAY RECAP ********************************************************************
127.0.0.1                  : ok=8   changed=7   unreachable=0    failed=0

我们将所有各种组件放在一起,形成一致的角色,现在已经安装并配置了Nginx!

2.5 事实(Facts)

请注意,运行剧本时的第一行总是“收集事实”。
在运行任何任务之前,Ansible将收集有关其配置的系统的信息。这些被称为事实,并且包括广泛的系统信息,如CPU核心数量,可用的ipv4和ipv6网络,挂载的磁盘,Linux发行版等等。

事实在“任务”或“模板”配置中通常很有用。例如,Nginx通常设置为使用与CPU内核一样多的工作处理器。知道这一点,您可以选择如下设置nginx.conf.j2文件的模板:

user www-data;
worker_processes {
   { ansible_processor_cores }};
pid /var/run/nginx.pid;

# And other configurations...

或者如果你具有多个CPU的服务器,则可以使用:

user www-data;
worker_processes {
   { ansible_processor_cores * ansible_processor_count }};
pid /var/run/nginx.pid;

# And other configurations...

所有的ansible facts全局变量都是以“anisble_”为前缀,并且可以在其他任何地方使用。
尝试对你的本地机器运行以下内容以查看可用的事实:

# Run against a local server
# Note that we say to use "localhost" instead of defining a hosts file here!
ansible -m setup --connection=local localhost

# Run against a remote server
ansible -i ./hosts remote -m setup

2.6 加密(Vault)

我们经常需要将敏感数据存储在我们的模板,文件或变量文件中; 这样安全性有一定要求的情况是不可避免的(当我们将这些敏感数据文件推送到远程Git仓库时,这是一个痛苦的事情)。Ansible有一个叫做Ansible Vault的解决方案。
Vault允许您加密任何Yaml文件,通常将其作用与变量文件,Vault不会加密文件和模板,只能使用Yaml文件。
在创建加密文件时,系统会询问您必须使用的密码,以便稍后在调用角色或Playbook时进行编辑。
将密码保存在安全的地方。

例如我们可以创建一个新的变量文件:

ansible-vault create vars/main.yml
Vault Password:

输入加密密码后,该文件将在您的默认编辑器(通常是Vim或Nano)中打开。
默认使用的编辑器由EDITOR环境变量定义。默认值通常是Vim。如果您不是Vim用户,可以通过设置环境变量来快速更改:

EDITOR=nano ansible-vault edit vars/main.yml

在大多数情况下,我们将使用ansible-vault create|edit /path/to/file.yml。更多可用的命令如下:

create - 创建一个新文件并进行加密
decrypt - 从加密文件创建明文文件
edit - 编辑已经存在的加密文件
encrypt - 加密现有的纯文本文件
rekey - 在加密文件中设置新密码

如果你有一个现有的配置文件要加密,请使用 ansible-vault encrypt /path/to/file.yml。

示例: users角色

我们创建一个名为“users”的角色:

cd ~/ansible-example/roles
ansible-galaxy init users

创建新用户并设置密码时,我使用Vault 。在用户角色中,您可以设置带有用户密码和公钥的变量文件,以添加到用户的authorized_keys文件(从而提供SSH访问权限)。公共SSH密钥在技术上是安全的,一般公众可以看到 - 所有人都可以使用它来允许你访问自己的服务器。在没有配对私钥的情况下,公钥是不能获得系统访问权限的,我们没有将密钥加入此角色。
以下是可以使用Vault创建和加密的示例变量文件。在编辑它时,它是纯文本。

~/ansible-example/roles/users/vars/main.yml:

admin_password: $6$lpQ1DqjZQ25gq9YW$mHZAmGhFpPVVv0JCYUFaDovu8u5EqvQi.Ih
deploy_password: $6$edOqVumZrYW9$d5zj1Ok/G80DrnckixhkQDpXl0fACDfNx2EHnC
common_public_key: ssh-rsa ALongSSHPublicKeyHere

请注意,用户的密码也是散列的。您可以阅读Ansible有关生成加密密码的文档,用户模块需要设置用户密码。作为一个快速入门,它在Ubuntu上看起来像这样:

# The whois package makes the mkpasswd
# command available on Ubuntu
$ sudo apt-get install -y whois

# Create a password hash
$ mkpasswd --method=SHA-512
Password:

这将生成一个散列密码供你与user模块一起使用。

Note:变量文件中的密码是散列的,但我仍然喜欢加密包含散列密码的yaml文件。这些文件通常包含未标记的数据,如API令牌或SSH私钥,使加密非常重要。

一旦你设置了用户密码并将公钥添加到变量文件中,我们就可以加密此文件,然后在任务中使用这些加密变量。

ansible-vault encrypt roles/users/vars/main.yml

然后我们可以编辑我们的任务文件,使用(加密)变量添加新用户:

这是文件~/ansible-example/roles/users/tasks/main.yml:

---
- name: Create Admin User
  user:
    name: admin
    password: '{
   { admin_password }}'
    groups: sudo
    append: yes
    shell: /bin/bash

- name: Add Admin Authorized Key
  authorized_key:
    user: admin
    key: '{
   { common_public_key }}'
    state: present

- name: Create Deploy User
  user:
    name: deploy
    password: '{
   { deploy_password }}'
    groups: www-data
    append: yes
    shell: /bin/bash

- name: Add Deployer Authorized Key
  authorized_key:
    user: deploy
    key: '{
   { common_public_key }}'
    state: present

这些任务使用该user模块来创建新用户,传递变量文件中设置的密码。
它还使用该authorized_key模块将SSH公钥作为SSH授权密钥添加到每个用户的服务器中。
加密变量的使用像在常规任务文件中使用一样。但是,为了运行此角色,我们需要告诉Ansible请求输入vault密码,以便它可以解密变量。
编辑我们的server.ymlPlaybook文件,调用user角色:

---
# Local connection here, yadda yadda yadda
- hosts: local
  connection: local
  sudo: yes
  roles:
    - nginx
    - user

要运行此Playbook,我们需要告知Ansible请求vault的密码,因为我们正在运行包含加密文件的角色:

ansible-playbook --ask-vault-pass -i ./hosts server.yml

3 总结

本篇文章带着做了如下工作:

  1. 安装了ansible
  2. 配置了ansible inventory文件(仅在不使用connection: local 时才需要)
  3. 同时在多个服务器上执行幂等的 ad-hoc命令
  4. 创建一个基本的Playbook来运行多个任务(tasks),并使用了处理程序(handlers)
  5. 将多个任务抽象为一个角色,以保持所有Nginx相关的操作在一个角色内
    • 展示了如何设置依赖关系
    • 展示了如何注册任务的“依赖”执行关系,当一个任务执行成功后再执行另一个任务
    • 展示了如何在我们的任务中使用更多的模板,文件和变量
  6. 展示了如何整合使用ansible事实(facts)
  7. 展示了如何使用ansible的vault来增加我们的变量的安全性

参考: https://serversforhackers.com/c/an-ansible2-tutorial

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pushiqiang/article/details/78126063

智能推荐

解决win10/win8/8.1 64位操作系统MT65xx preloader线刷驱动无法安装_mt65驱动-程序员宅基地

文章浏览阅读1.3w次。转载自 http://www.miui.com/thread-2003672-1-1.html 当手机在刷错包或者误修改删除系统文件后会出现无法开机或者是移动定制(联通合约机)版想刷标准版,这时就会用到线刷,首先就是安装线刷驱动。 在XP和win7上线刷是比较方便的,用那个驱动自动安装版,直接就可以安装好,完成线刷。不过现在也有好多机友换成了win8/8.1系统,再使用这个_mt65驱动

SonarQube简介及客户端集成_sonar的客户端区别-程序员宅基地

文章浏览阅读1k次。SonarQube是一个代码质量管理平台,可以扫描监测代码并给出质量评价及修改建议,通过插件机制支持25+中开发语言,可以很容易与gradle\maven\jenkins等工具进行集成,是非常流行的代码质量管控平台。通CheckStyle、findbugs等工具定位不同,SonarQube定位于平台,有完善的管理机制及强大的管理页面,并通过插件支持checkstyle及findbugs等既有的流..._sonar的客户端区别

元学习系列(六):神经图灵机详细分析_神经图灵机方法改进-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏27次。神经图灵机是LSTM、GRU的改进版本,本质上依然包含一个外部记忆结构、可对记忆进行读写操作,主要针对读写操作进行了改进,或者说提出了一种新的读写操作思路。神经图灵机之所以叫这个名字是因为它通过深度学习模型模拟了图灵机,但是我觉得如果先去介绍图灵机的概念,就会搞得很混乱,所以这里主要从神经图灵机改进了LSTM的哪些方面入手进行讲解,同时,由于模型的结构比较复杂,为了让思路更清晰,这次也会分开几..._神经图灵机方法改进

【机器学习】机器学习模型迭代方法(Python)-程序员宅基地

文章浏览阅读2.8k次。一、模型迭代方法机器学习模型在实际应用的场景,通常要根据新增的数据下进行模型的迭代,常见的模型迭代方法有以下几种:1、全量数据重新训练一个模型,直接合并历史训练数据与新增的数据,模型直接离线学习全量数据,学习得到一个全新的模型。优缺点:这也是实际最为常见的模型迭代方式,通常模型效果也是最好的,但这样模型迭代比较耗时,资源耗费比较多,实时性较差,特别是在大数据场景更为困难;2、模型融合的方法,将旧模..._模型迭代

base64图片打成Zip包上传,以及服务端解压的简单实现_base64可以装换zip吗-程序员宅基地

文章浏览阅读2.3k次。1、前言上传图片一般采用异步上传的方式,但是异步上传带来不好的地方,就如果图片有改变或者删除,图片服务器端就会造成浪费。所以有时候就会和参数同步提交。笔者喜欢base64图片一起上传,但是图片过多时就会出现数据丢失等异常。因为tomcat的post请求默认是2M的长度限制。2、解决办法有两种:① 修改tomcat的servel.xml的配置文件,设置 maxPostSize=..._base64可以装换zip吗

Opencv自然场景文本识别系统(源码&教程)_opencv自然场景实时识别文字-程序员宅基地

文章浏览阅读1k次,点赞17次,收藏22次。Opencv自然场景文本识别系统(源码&教程)_opencv自然场景实时识别文字

随便推点

ESXi 快速复制虚拟机脚本_exsi6.7快速克隆centos-程序员宅基地

文章浏览阅读1.3k次。拷贝虚拟机文件时间比较长,因为虚拟机 flat 文件很大,所以要等。脚本完成后,以复制虚拟机文件夹。将以下脚本内容写入文件。_exsi6.7快速克隆centos

好友推荐—基于关系的java和spark代码实现_本关任务:使用 spark core 知识完成 " 好友推荐 " 的程序。-程序员宅基地

文章浏览阅读2k次。本文主要实现基于二度好友的推荐。数学公式参考于:http://blog.csdn.net/qq_14950717/article/details/52197565测试数据为自己随手画的关系图把图片整理成文本信息如下:a b c d e f yb c a f gc a b dd c a e h q re f h d af e a b gg h f bh e g i di j m n ..._本关任务:使用 spark core 知识完成 " 好友推荐 " 的程序。

南京大学-高级程序设计复习总结_南京大学高级程序设计-程序员宅基地

文章浏览阅读367次。南京大学高级程序设计期末复习总结,c++面向对象编程_南京大学高级程序设计

4.朴素贝叶斯分类器实现-matlab_朴素贝叶斯 matlab训练和测试输出-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏12次。实现朴素贝叶斯分类器,并且根据李航《统计机器学习》第四章提供的数据训练与测试,结果与书中一致分别实现了朴素贝叶斯以及带有laplace平滑的朴素贝叶斯%书中例题实现朴素贝叶斯%特征1的取值集合A1=[1;2;3];%特征2的取值集合A2=[4;5;6];%S M LAValues={A1;A2};%Y的取值集合YValue=[-1;1];%数据集和T=[ 1,4,-1;..._朴素贝叶斯 matlab训练和测试输出

Markdown 文本换行_markdowntext 换行-程序员宅基地

文章浏览阅读1.6k次。Markdown 文本换行_markdowntext 换行

错误:0xC0000022 在运行 Microsoft Windows 非核心版本的计算机上,运行”slui.exe 0x2a 0xC0000022″以显示错误文本_错误: 0xc0000022 在运行 microsoft windows 非核心版本的计算机上,运行-程序员宅基地

文章浏览阅读6.7w次,点赞2次,收藏37次。win10 2016长期服务版激活错误解决方法:打开“注册表编辑器”;(Windows + R然后输入Regedit)修改SkipRearm的值为1:(在HKEY_LOCAL_MACHINE–》SOFTWARE–》Microsoft–》Windows NT–》CurrentVersion–》SoftwareProtectionPlatform里面,将SkipRearm的值修改为1)重..._错误: 0xc0000022 在运行 microsoft windows 非核心版本的计算机上,运行“slui.ex