如何在 Ubuntu 14.04 上使用 Ansible 配置 Apache

介绍

Apache 是目前在互联网上使用的最流行的网页服务器之一,它很容易在Ubuntu和Debian等Linux发行版上设置和配置,因为它包含在包存库中,并包含一个默认配置,可以从盒子中工作。

Ansible 是一个自动化工具,它允许您远程配置系统,安装软件,并跨一大批服务器执行复杂任务而无需手动登录每个服务器. 与其他替代品不同,Ansible被安装在一个单一的主机上,它甚至可以作为你的本地机,并使用SSH与每个远程主机通信. 这使得它在配置新服务器时可以令人难以置信地快活地快活地运行,因为每个新服务器上都没有安装先决条件的软件包. 它使用和理解非常容易,因为它使用基于简单模块的语法,使用`yaml'格式的_playbooks_.

前提条件

对于本教程,我们将安装Ansible在新的Ubuntu 14.04主Droplet上,并使用它来配置Apache在第二个Droplet上。

对于这个教程,你将需要:

**注:本教程遵循现有教程中所解释的概念: 如何在Ubuntu或Debian VPS上配置Apache Web Server

步骤 1 - 配置 Ansible

在本节中,我们将配置 Ansible 来管理您的服务器。

第一步,一旦安裝了 Ansible,就是告訴 Ansible 要與哪個主機交談. 要做到這一點,我們需要創建一個 Ansible 主機檔案. Ansible 主機檔案包含群組的主機,我們在執行 Ansible 命令時所指的。 默認時,這位主機位於 `/etc/ansible/hosts。 然而,這在您的系統範圍內適用,經常需要管理員權限。 相反,為了使事情更簡單,我們需要告訴 Ansible 使用本地主機檔案。

Ansible 始终在正在运行的本地目录中寻找一个 ansible.cfg 文件,如果找到它,它会将全球配置与本地值叠加在一起. 考虑到这一点,我们只需要告诉 Ansible 我们希望在本地目录中使用主机文件,而不是全球文件。

创建一个新的目录(我们将用于本教程的其余部分)。

1mkdir ansible-apache

移动到新目录。

1cd ~/ansible-apache/

创建一个名为ansible.cfg的新文件,然后打开以进行编辑。

1nano ansible.cfg

在该文件中,我们希望在hostfile配置选项中添加hosts的值,在[默认]组中。

1[defaults]
2hostfile = hosts

接下来,需要写主机文件. 对于主机文件,有很多选项可用. 但是,我们可以从一个非常简单的开始。

创建一个主机文件,并打开它进行编辑。

1nano hosts

将下列内容复制到主机文件中。

1[apache]
2secondary_server_ip ansible_ssh_user=username

这指定了一个名为apache的主机组,其中包含一个主机. 将secondary_server_ip替换为次要服务器的主机名称或 IP 地址,并将用户名替换为您的 SSH 用户名。

**注:如果您正在运行 Ansible 作为与目标主机相同的用户,则ansible_ssh_user=username组件是可选的。

要测试Ansible是否在工作并能与您的主机交谈,您可以运行一个基本的ansible命令。Ansible配备了许多 默认模块,但一个好的开始是 ping模块。

基本使用ansible命令接受主机组和模块名称:ansible <group> -m <module>

1ansible apache -m ping

输出应该是这样的:

1111.111.111.111 | success >> {
2    "changed": false,
3    "ping": "pong"
4}

另一个用于测试的 Ansible 模块是 command 模块. 它在主机上运行自定义命令并返回结果. 若要使用 'echo' 运行 'command' 命令,这是一个 Unix 命令,该命令响应到终端的字符串,请输入以下命令。

1ansible apache -m command -a "/bin/echo hello sammy"

输出应该是这样的:

1111.111.111.111 | success | rc=0 >>
2hello sammy

这是Ansible的基本用途。真正的力量来自创建包含多个Ansible任务的玩本。

第2步:创建一本剧本

在本节中,我们将创建一个基本的Ansible播放簿,以便您轻松运行更复杂的模块。

一个非常基本的Ansible播放簿是一个单一的yaml文件,它指定了主机组和一个或多个任务在指定组内的主机上运行。

让我们创建上面的Hello Sammy命令的基本播放书版本。

创建一个名为 apache.yml 的文件,然后打开以进行编辑。

1nano apache.yml

将下列文本复制到文件中,然后保存并关闭它。

1---
2- hosts: apache
3  tasks:
4    - name: run echo command
5      command: /bin/echo hello sammy

主机:apache声明位于顶部,该声明告诉Ansible我们正在使用apache主机组,这相当于通过ansible命令传输它。接下来有任务列表。在这个示例中,我们有一个名为运行响应命令的任务。这只是一个描述,旨在让用户了解该任务正在做什么。最后,命令: /bin/echo hello sammy行运行命令模块,具有参数/bin/echo hello sammy

「ansible-playbook」命令用于运行播放书籍,最简单的用途是「ansible-playbook your-playbook.yml」。

1ansible-playbook apache.yml

产量应该是这样的。

 1PLAY [apache] *****************************************************************
 2
 3GATHERING FACTS ***************************************************************
 4ok: [111.111.111.111]
 5
 6TASK: [run echo command] ******************************************************
 7changed: [111.111.111.111]
 8
 9PLAY RECAP ********************************************************************
10111.111.111.111            : ok=2 changed=1 unreachable=0 failed=0

这里要注意的最重要的是,播放本不返回模块的输出,所以与我们在步骤 1 中使用的直接命令不同,我们无法看到‘hello sammy’是否实际上被打印。

第3步:安装Apache

现在我们已经介绍了播放本,我们将写下安装Apache Web 服务器的任务。

通常在Ubuntu上,安裝Apache是一個簡單的例子,即透過apt-get安裝「apache2」套件。 要透過 Ansible進行安裝,我們使用了Ansible的 apt模塊。

  • 名称 :要安装的包的名称,要么是一个单一的包名称,要么是包列表。 * ** 状态** :接受最近缺席现在 最新确保安装了最新版本,现在只检查安装了,如果安装了,则删除。

:除了「apt」以外的包管理器(http://docs.ansible.com/list_of_packaging_modules.html)。每个模块页面都有例子,通常涵盖所有主要用例,这使得很容易了解如何使用每个模块。

现在让我们用apt模块更新我们的apache.yml播放簿,而不是command模块。

1nano apache.yml

删除当前的文本,并将以下文本复制到其中。

1---
2- hosts: apache
3  sudo: yes
4  tasks:
5    - name: install apache2
6      apt: name=apache2 update_cache=yes state=latest

「apt」行安装了「apache2」包(「name=apache2」),并确保我们已经更新了缓存(「update_cache=yes」)。

除非您的 Playbook 在每个主机上运行为,否则sudo将被要求以确保正确的特权。 Ansible 支持sudo作为 Playbook 中的简单选项的一部分。

现在就开玩具书吧。

1ansible-playbook apache.yml --ask-sudo-pass

--ask-sudo-pass 旗帜将提示您在次要 Droplet 上使用 sudo 密码. 这是必要的,因为安装需要 root 特权;我们迄今为止所执行的其他命令没有。

产量应该是这样的。

 1PLAY [apache] *****************************************************************
 2
 3GATHERING FACTS ***************************************************************
 4ok: [111.111.111.111]
 5
 6TASK: [install apache2] *******************************************************
 7changed: [111.111.111.111]
 8
 9PLAY RECAP ********************************************************************
10111.111.111.111            : ok=2 changed=1 unreachable=0 failed=0

如果您在浏览器中访问您的二级服务器的主机名称或 IP 地址,您现在应该得到一个 Apache2 Ubuntu 默认页面 来欢迎您,这意味着您在服务器上有一个工作 Apache 安装,并且您尚未手动连接到它来运行命令。

在这一点上要注意的一个重要概念是 idempotence,这决定了 Ansible 模块应该如何行为. 这个想法是,你可以重复运行相同的命令,但如果一切都配置在第一次运行时,那么所有后续运行都不会做出任何变化。

例如,再次运行相同的 Playbook 命令。

1ansible-playbook apache.yml --ask-sudo-pass

输出应该是这样的,请注意变更=0部分。

 1PLAY [apache] *****************************************************************
 2
 3GATHERING FACTS ***************************************************************
 4ok: [111.111.111.111]
 5
 6TASK: [install apache2] *******************************************************
 7ok: [111.111.111.111]
 8
 9PLAY RECAP ********************************************************************
10111.111.111.111            : ok=2 changed=0 unreachable=0 failed=0

這告訴你「apache2」包已經安裝了,所以沒有什麼變化. 當處理複雜的播放簿在許多主機上時,能夠識別不同主機變得非常有用。 例如,如果你注意到一個主機 總是 需要更新特定的配置,那麼在那個主機上很可能有一個使用者或流程正在改變它。

第4步:配置Apache模块

现在Apache已安装,我们需要允许一个模块被Apache使用。

让我们确保mod_rewrite模块已启用到Apache。通过SSH,可以通过使用a2enmod并重新启动Apache来轻松完成此操作,但是,我们也可以通过使用apache2_module模块(http://docs.ansible.com/apache2_module_module.html)和任务处理器重新启动apache2来非常轻松地使用Ansible。

apache2_module模块有两个选项:

  • 名称 - 要启用的模块的名称,如重写。 * ** 状态** - 要么是存在缺席,取决于是否需要启用或禁用该模块。

打开 apache.yml 进行编辑。

1nano apache.yml

更新文件以包含此任务. 该文件现在应该是这样的:

1---
2- hosts: apache
3  sudo: yes
4  tasks:
5    - name: install apache2
6      apt: name=apache2 update_cache=yes state=latest
7
8    - name: enabled mod_rewrite
9      apache2_module: name=rewrite state=present

但是,我们需要在模块启用后重新启动apache2。 一个选项是添加一个任务来重新启动apache2,但我们不希望每次我们应用我们的播放簿都会运行。

要做到这一点,我们需要将通知选项添加到apache2_module任务中,然后我们可以使用服务(http://docs.ansible.com/service_module.html)模块在处理器中重新启动apache2

结果是一本看起来像这样的剧本:

 1---
 2- hosts: apache
 3  sudo: yes
 4  tasks:
 5    - name: install apache2
 6      apt: name=apache2 update_cache=yes state=latest
 7
 8    - name: enabled mod_rewrite
 9      apache2_module: name=rewrite state=present
10      notify:
11        - restart apache2
12
13  handlers:
14    - name: restart apache2
15      service: name=apache2 state=restarted

现在,重新启动Playbook。

1ansible-playbook apache.yml --ask-sudo-pass

产量应该看起来像:

 1PLAY [apache] *****************************************************************
 2
 3GATHERING FACTS ***************************************************************
 4ok: [111.111.111.111]
 5
 6TASK: [install apache2] *******************************************************
 7ok: [111.111.111.111]
 8
 9TASK: [enabled mod_rewrite] ***************************************************
10changed: [111.111.111.111]
11
12NOTIFIED: [restart apache2] ***************************************************
13changed: [111.111.111.111]
14
15PLAY RECAP ********************************************************************
16111.111.111.111            : ok=4 changed=2 unreachable=0 failed=0

现在,重新运行命令,不应该有任何更改,并且将不会列出重启任务。

第5步:配置Apache选项

现在我们有一个工作Apache安装,我们的所需模块启用,我们需要配置Apache。

默认情况下,Apache在端口80上倾听所有HTTP流量。为了教程,让我们假设我们希望Apache在端口8081上倾听,而不是。

1/etc/apache2/ports.conf
2    Listen 80
3
4/etc/apache2/sites-available/000-default.conf
5    <VirtualHost *:80>

要做到这一点,我们可以使用 lineinfile模块. 该模块非常强大,通过使用其许多不同的配置选项,它允许您对主机上的现有文件进行各种更改。

  • dest - 作为命令的一部分更新的文件. * ** regexp** - 用来匹配要更换的现有行的常规表达式. * ** line** - 要插入到文件中的行,要么取代regexp行,要么作为一个新的行。

** 注意** :lineinfile模块将附加在文件末尾的行,如果它不匹配现有的行与regexp 选项insertbeforeinsertafter可以指定行添加它之前或之后,而不是结束,如果需要。

要更新端口从808081,我们需要做的就是寻找定义端口80的现有行,然后将其更改为定义端口8081

打开apache.yml文件进行编辑。

1nano apache.yml

更改额外的行,使文件看起来像这样:

 1---
 2- hosts: apache
 3  sudo: yes
 4  tasks:
 5    - name: install apache2
 6      apt: name=apache2 update_cache=yes state=latest
 7
 8    - name: enabled mod_rewrite
 9      apache2_module: name=rewrite state=present
10      notify:
11        - restart apache2
12
13    - name: apache2 listen on port 8081
14      lineinfile: dest=/etc/apache2/ports.conf regexp="^Listen 80" line="Listen 8081" state=present
15      notify:
16        - restart apache2
17
18    - name: apache2 virtualhost on port 8081
19      lineinfile: dest=/etc/apache2/sites-available/000-default.conf regexp="^<VirtualHost \*:80>" line="<VirtualHost *:8081>" state=present
20      notify:
21        - restart apache2
22
23  handlers:
24    - name: restart apache2
25      service: name=apache2 state=restarted

重要的是要注意,我们也需要重新启动apache2作为这个过程的一部分,我们可以重复使用相同的处理器,但尽管发生了多个更改,但 Hanlder 只会启动一次。

现在就开玩具书吧。

1ansible-playbook apache.yml --ask-sudo-pass

一旦Ansible完成,您应该能够在浏览器中访问您的主机,它将响应端口8081,而不是端口80。在大多数网页浏览器中,通过在URL的末尾添加:端口可以轻松实现这一点:http://111.111.111.111:8081/`。

lineinfile模块非常强大,并使现有配置非常容易。唯一的吸引力是,你需要知道你正在改变的文件需要什么,但它支持各种选项,支持最简单的使用案例。

第6步:配置虚拟主机

Ansible 提供了几种模块,可以将本地(向 Ansible)模板文件复制到主机。为此目的最常用的两个模块是 copy 模块和 template 模块。 复制模块将文件复制为 as-is 并不会对其进行更改,而更强大的 template 模块则在模板上复制,并通过使用{{ variable }}来对您指定的区域进行可变替代。

在本节中,我们将使用 template模块在您的服务器上配置一个新的虚拟主机. 将有许多变化,所以我们将逐步解释它们,并在本步结束时包括整个更新的 apache.yml 文件。

创建虚拟主机配置

第一步是创建一个新的虚拟主机配置,我们将在主Droplet上创建虚拟主机配置文件,并使用Ansible将其上传到辅助Droplet。

以下是我们可以作为我们自己的配置的起点使用的基本虚拟主机配置的示例. 请注意,下面显示的端口号和域名都被硬编码到配置中。

1<VirtualHost *:8081>
2    ServerAdmin webmaster@example.com
3    ServerName example.com
4    ServerAlias www.example.com
5    DocumentRoot /var/www/example.com
6    ErrorLog ${APACHE_LOG_DIR}/error.log
7    CustomLog ${APACHE_LOG_DIR}/access.log combined
8</VirtualHost>

创建一个名为virtualhost.conf的新文件。

1nano virtualhost.conf

将以下内容粘贴到「virtualhost.conf」中,因为我们正在使用模板,所以更改上面硬编码的值为变量是很好的想法,以便在未来更改它们。

1<VirtualHost *:{{ http_port }}>
2    ServerAdmin webmaster@{{ domain }}
3    ServerName {{ domain }}
4    ServerAlias www.{{ domain }}
5    DocumentRoot /var/www/{{ domain }}
6    ErrorLog ${APACHE_LOG_DIR}/error.log
7    CustomLog ${APACHE_LOG_DIR}/access.log combined
8</VirtualHost>

使用模板变量

接下来,我们需要更新我们的玩本,以推动模板并使用变量。

第一步是将一个部分添加到变量演示书中,它被称为vars,并与hosts,sudo,taskshandlers相同。

1---
2- hosts: apache
3  sudo: yes
4  vars:
5    http_port: 80
6    domain: example.com
7  tasks:
8    - name: install apache2
9...

可在任务和模板中使用变量,所以我们可以更新现有的lineinfile模块以使用指定的http_port,而不是我们之前指定的硬编码的8081

1lineinfile: dest=/etc/apache2/ports.conf regexp="^Listen " line="Listen {{ http_port }}" state=present
1lineinfile: dest=/etc/apache2/sites-available/000-default.conf regexp="^<VirtualHost \*:" line="<VirtualHost *:{{ http_port }}>"

添加模块模块

下一步是添加模板模块以将配置文件推到主机上,我们将使用这些选项来使它发生:

  • dest - 目的地文件路径将更新的模板保存到主机(s),即 /etc/apache2/sites-available/{{域 }}.conf. * ** src** - 源模板文件,即 virtualhost.conf

将这些应用到您的玩本中会导致一个看起来像这样的任务:

1- name: create virtual host file
2  template: src=virtualhost.conf dest=/etc/apache2/sites-available/{{ domain }}.conf

启用虚拟主机

我们现在需要做的就是启用Apache内部的虚拟主机,这可以通过两种方式完成:通过运行sudo a2ensite example.com命令或手动将配置文件连接到/etc/apache2/sites-enabled/

使用方法非常简单,正如我们上面所发现的:

1- name: a2ensite {{ domain }}
2  command: a2ensite {{ domain }}
3  notify:
4  - restart apache2

防止额外工作

最后,命令模块需要知道何时应该运行,何时不应该运行,所以如果播放簿运行多次,该模块不会运行不必要。

这样做是使用创建选项,这允许您告诉模块在模块执行过程中正在创建什么文件. 如果文件存在,模块不会运行. 因为Apache在启用网站时创建了一个simlink,检查它解决了问题。

变化将是这样的:

1- name: a2ensite {{ domain }}
2  command: a2ensite {{ domain }}
3  args:
4    creates: /etc/apache2/sites-enabled/{{ domain }}.conf
5  notify:
6  - restart apache2

这是列出模块选项的可选方式,在这种情况下,可以消除模块选项和命令本身之间的任何混淆。

最后的apache.yml播放书

现在让我们应用这些更改,打开apache.yml

1nano apache.yml

隨著上述所有變更,請更改您的「apache.yml」播放簿,看起來像這樣。

 1---
 2- hosts: apache
 3  sudo: yes
 4  vars:
 5    http_port: 80
 6    domain: example.com
 7  tasks:
 8    - name: install apache2
 9      apt: name=apache2 update_cache=yes state=latest
10
11    - name: enabled mod_rewrite
12      apache2_module: name=rewrite state=present
13      notify:
14        - restart apache2
15
16    - name: apache2 listen on port {{ http_port }}
17      lineinfile: dest=/etc/apache2/ports.conf regexp="^Listen " line="Listen {{ http_port }}" state=present
18      notify:
19        - restart apache2
20
21    - name: apache2 virtualhost on port {{ http_port }}
22      lineinfile: dest=/etc/apache2/sites-available/000-default.conf regexp="^<VirtualHost \*:" line="<VirtualHost *:{{ http_port }}>"
23      notify:
24        - restart apache2
25
26    - name: create virtual host file
27      template: src=virtualhost.conf dest=/etc/apache2/sites-available/{{ domain }}.conf
28
29    - name: a2ensite {{ domain }}
30      command: a2ensite {{ domain }}
31      args:
32        creates: /etc/apache2/sites-enabled/{{ domain }}.conf
33      notify:
34        - restart apache2
35
36  handlers:
37    - name: restart apache2
38      service: name=apache2 state=restarted

保存并关闭文件,然后运行播放簿。

1ansible-playbook apache.yml --ask-sudo-pass

如果您现在在浏览器中访问您次要 Droplet 的主机名或 IP 地址,您会看到它再次响应端口 80,而不是端口 8081. 接下来,请访问我们为新虚拟主机指定的域(即 example.com) 因为我们还没有添加任何文件,它应该显示一个 Apache 404` 错误页面而不是 Apache 欢迎页面。

第7步:为您的网站使用Git存储库

在本节中,我们将使用Ansible来克隆Git存储库,以便设置您的网站内容。

每个网站都需要内容,虽然 SSH 并手动克隆 Git 存储库以设置新网站是正常的,但 Ansible 为我们提供了自动执行所需的工具。

git模块有很多选项,本教程的相关选项是:

  • ** 底** -- 检查寄存器所在的主机上的路径 。
  • repo -- 将被克隆的寄存器 URL 。 这必须是东道主可以访问的。
  • ** 更新** -- 当设定为`否'时,可防止 已存在时可更新寄存器 。
  • ** 接受_hostkey** -- 要求SSH在通过SSH连接时接受任何未知的主机密钥. 这非常有用,因为它省去通过SSH登录接受第一次登录尝试的需要,但它确实取消了手动检查主机签名的能力. 根据您的仓库, 您可能需要此选项 。 .

对于本教程的目的,有一个简单的Git存储库,有一个单一的index.html页面,可以克隆到您的主机上。

1- name: clone basic html template
2  git: repo=https://github.com/do-community/ansible-apache-tutorial.git dest=/var/www/example.com update=no

但是,如果你现在运行了 Playbook,你可能会遇到一个错误。我们首先需要安装git包,以便 Ansible 可以使用它来克隆存储库。apt任务需要更新以安装apache2包和git包。检查 apt的文档告诉我们名称选项只需要一个包,所以这不会有帮助。

Ansible 提供了指定要循环并将任务应用于每个项目的列表的功能,这些项目将使用with_items选项作为任务的一部分来指定,我们的apt任务将更新到这样:

1- name: install packages
2  apt: name={{ item }} update_cache=yes state=latest
3  with_items:
4    - apache2
5    - git

项目列表使用项目变量,并将执行列表中的每个项目的任务。

再次打开 apache.yml。

1nano apache.yml

更新播放簿以匹配以下内容:

 1---
 2- hosts: apache
 3  sudo: yes
 4
 5  vars:
 6    http_port: 80
 7    domain: example.com
 8
 9  tasks:
10
11    - name: install packages
12      apt: name={{ item }} update_cache=yes state=latest
13      with_items:
14        - apache2
15        - git
16
17    - name: enabled mod_rewrite
18      apache2_module: name=rewrite state=present
19      notify:
20        - restart apache2
21
22    - name: apache2 listen on port {{ http_port }}
23      lineinfile: dest=/etc/apache2/ports.conf regexp="^Listen " line="Listen {{ http_port }}" state=present
24      notify:
25        - restart apache2
26
27    - name: apache2 virtualhost on port {{ http_port }}
28      lineinfile: dest=/etc/apache2/sites-available/000-default.conf regexp="^<VirtualHost \*:" line="<VirtualHost *:{{ http_port }}>"
29      notify:
30        - restart apache2
31
32    - name: create virtual host file
33      template: src=virtualhost.conf dest=/etc/apache2/sites-available/{{ domain }}.conf
34
35    - name: a2ensite {{ domain }}
36      command: a2ensite {{ domain }}
37      args:
38        creates: /etc/apache2/sites-enabled/{{ domain }}.conf
39      notify:
40        - restart apache2
41
42    - name: clone basic html template
43      git: repo=https://github.com/do-community/ansible-apache-tutorial.git dest=/var/www/example.com update=no
44
45  handlers:
46    - name: restart apache2
47      service: name=apache2 state=restarted

保存文件并运行播放簿。

1ansible-playbook apache.yml --ask-sudo-pass

它应该安装git并成功克隆存储库. 当您从步骤 6 访问虚拟主机时,您现在应该看到其他东西,而不是 404 错误。

总之,你现在已经安装了Git,并且通过Git将一个基本的HTML页面克隆到你的新的虚拟主机上。你仍然不需要手动SSH命令。

结论

我们刚刚创建了一个 Ansible Playbook 来自动化配置您的主机以运行 Apache Web Server 的整个过程,具有虚拟主机和 Git 存储库. 所有这些都实现了,而无需直接登录服务器,最好的部分是您可以对大多数 Ubuntu 服务器运行新的 Playbook 以实现相同的结果。

** 注意** :如果您的主机已经安装和修改了Apache,您可能需要处理每个更改以将其恢复到所需状态。

Ansible是令人难以置信的强大,也有一个非常容易的学习曲线. 你可以开始使用本教程中涵盖的基本概念,或留在这个级别,或学习更多,以获得真正复杂的部分。

你可以浏览 Ansible 模块列表以查看其他 Ansible 能做什么。

Published At
Categories with 技术
comments powered by Disqus