如何在Ubuntu18.04上使用Ansible自动化初始服务器设置
介绍
由于现代应用程序环境的一次性性质,服务器自动化现在在系统管理中发挥着重要作用。 配置管理工具,例如Ansible,通常用于通过为新服务器建立标准程序来简化服务器设置自动化的过程,同时减少与手动设置相关的人为错误。
Ansible 提供了一个简单的架构,不需要在节点上安装特殊软件。 它还提供了一组强大的功能和内置模块,有助于编写自动化脚本。
本指南解释了如何使用 Ansible 自动执行我们的 Ubuntu 18.04 服务器初始服务器设置指南 中包含的步骤。
先决条件
为了执行我们在本指南中讨论的剧本提供的自动设置,您需要:
- 一个 Ansible 控制节点:安装了 Ansible 并配置为使用 SSH 密钥连接到 Ansible 主机的 Ubuntu 18.04 机器。 确保控制节点具有具有 sudo 权限的普通用户并启用了防火墙,如我们的 初始服务器设置 指南中所述。 要设置 Ansible,请按照我们关于 如何在 Ubuntu 18.04 上安装和配置 Ansible 的指南进行操作。
- 一个或多个 Ansible 主机:一个或多个远程 Ubuntu 18.04 服务器。
在继续之前,您首先需要确保您的 Ansible 控制节点能够连接并在您的 Ansible 主机上执行命令。 如需连接测试,请查看 如何在 Ubuntu 18.04 上安装和配置 Ansible 的第 3 步。
这个剧本有什么作用?
这个 Ansible playbook 提供了一种替代手动运行 Ubuntu 18.04 初始服务器设置指南 和 在 Ubuntu 18.04 上设置 SSH 密钥的指南中概述的过程的替代方法。
运行此 playbook 将在您的 Ansible 主机上执行以下操作:
- 安装
aptitude
,这是 Ansible 首选的apt
包管理器的替代方案。 - 创建管理组 wheels 并将其配置为 passwordless sudo。
- 创建一个新的 sudo 用户。
- 复制本地 SSH 公钥并将其包含在远程主机上新管理用户的
authorized_keys
文件中。 - 为 root 用户禁用基于密码的身份验证。
- 安装系统包。
- 将 UFW 防火墙配置为仅允许 SSH 连接并拒绝任何其他请求。
一旦 playbook 完成运行,您将拥有一个新用户,您可以使用该用户登录到服务器。
如何使用本手册
您需要做的第一件事是从 do-community/ansible-playbooks 存储库获取初始服务器设置手册及其依赖项。 我们将此存储库克隆到 Ansible 控制节点内的本地文件夹。
如果这是您第一次使用 do-community/ansible-playbooks
存储库,您应该首先将存储库克隆到您的控制器节点:
cd ~ git clone https://github.com/do-community/ansible-playbooks.git cd ansible-playbooks
如果您之前按照不同的指南克隆了此存储库,请访问您现有的 ansible-playbooks
副本并运行 git pull
命令以确保您已更新内容:
cd ~/ansible-playbooks git pull
我们感兴趣的文件位于 setup_ubuntu1804
文件夹中,其结构如下:
setup_ubuntu1804 ├── playbook.yml └── vars └── default.yml
以下是每个文件的内容:
vars/default.yml
:用于自定义剧本设置的变量文件。playbook.yml
:剧本文件,包含要在远程服务器上执行的任务。
我们将编辑 playbook 的变量文件以自定义其值。 访问 setup_ubuntu1804
目录并使用您选择的命令行编辑器打开 vars/default.yml
文件:
cd setup_ubuntu1804 nano vars/default.yml
此文件包含一些需要您注意的变量:
变量/default.yml
--- create_user: sammy copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" sys_packages: [ 'curl', 'vim', 'git', 'ufw']
以下列表包含每个变量的简要说明以及您可能希望如何更改它们:
create_user
:将创建的 sudo 用户的名称。 在这个例子中,我们将使用 sammy。copy_local_key
:本地 SSH 公钥文件的路径,应该复制到远程服务器并为新的 sudo 用户添加为authorized_key
。 默认值使用 lookup 插件在 Ansible 控制节点获取当前系统用户默认公钥的完整路径。sys_packages
:一个数组,包含您希望在主机上安装的软件包列表,作为初始服务器设置的一部分。 在此示例中,我们将确保存在curl
、vim
、git
和ufw
包。
更新完 vars/default.yml
中的变量后,保存并关闭此文件。 如果您使用 nano
,请按 CTRL + X
、Y
,然后按 ENTER
。
您现在已准备好在一台或多台服务器上运行此 playbook。 默认情况下,大多数剧本都配置为在库存中的每台服务器上执行。 我们可以使用 -l
标志来确保只有一部分服务器或单个服务器受到剧本的影响。 我们还可以使用 -u
标志来指定我们使用远程服务器上的哪个用户来连接和执行远程主机上的 playbook 命令。
要仅在 server1
上执行 playbook,连接为 root
,可以使用以下命令:
ansible-playbook playbook.yml -l server1 -u root
你会得到类似这样的输出:
Output PLAY [all] ***************************************************************************************************************************** TASK [Gathering Facts] ***************************************************************************************************************** ok: [server1] TASK [Install Prerequisites] *********************************************************************************************************** changed: [server1] TASK [Make sure we have a 'wheel' group] *********************************************************************************************** changed: [server1] TASK [Allow 'wheel' group to have passwordless sudo] *********************************************************************************** changed: [server1] TASK [Create a new regular user with sudo privileges] ********************************************************************************** changed: [server1] TASK [Set authorized key for remote user] ********************************************************************************************** changed: [server1] TASK [Disable password authentication for root] **************************************************************************************** changed: [server1] TASK [Update apt] ********************************************************************************************************************** changed: [server1] TASK [Install required system packages] ************************************************************************************************ ok: [server1] TASK [UFW - Allow SSH connections] ***************************************************************************************************** changed: [server1] TASK [UFW - Deny all other incoming traffic by default] ******************************************************************************** changed: [server1] PLAY RECAP ***************************************************************************************************************************** server1 : ok=11 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
注意:有关如何运行 Ansible playbook 的更多信息,请查看我们的 Ansible 备忘单指南 。
剧本执行完成后,您将能够使用以下命令登录服务器:
ssh sammy@server_host_or_IP
请记住将 sammy 替换为 create_user
变量定义的用户,并将 server_host_or_IP 替换为您的服务器的主机名或 IP 地址。
如果您已将 copy_local_key
变量更改为指向自定义 SSH 密钥(不是您当前系统用户的密钥),您需要提供一个额外的参数来指定通过 SSH 连接时对应的私钥的位置作为新用户:
ssh sammy@server_host_or_IP -i ~/.ssh/ansible_controller_key
登录服务器后,您可以检查 UFW 防火墙的活动规则以确认其配置正确:
sudo ufw status
你应该得到类似这样的输出:
OutputStatus: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
这意味着 UFW 防火墙已成功启用。 由于这是 playbook 中的最后一个任务,因此它确认 playbook 已在此服务器上完全执行。
剧本内容
您可以在 DigitalOcean Community Playbooks 中的 ansible-playbooks 存储库 中找到本教程中介绍的初始服务器设置手册。 要直接复制或下载脚本内容,请单击每个脚本顶部的 Raw 按钮。
为方便起见,此处还包含了剧本的全部内容及其相关文件。
变量/default.yml
default.yml
变量文件包含将在 playbook 任务中使用的值,例如将创建的用户名和应作为初始服务器设置的一部分安装的包。
变量/default.yml
--- create_user: sammy copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" sys_packages: [ 'curl', 'vim', 'git', 'ufw']
剧本.yml
playbook.yml
文件是定义此设置中的所有任务的位置。 它首先定义应作为此设置目标的服务器组 (all
),然后使用 become: true
定义应使用权限提升执行的任务 ([ X197X]) 默认情况下。 然后,它包含 vars/default.yml
变量文件以加载配置选项。
剧本.yml
--- - hosts: all become: true vars_files: - vars/default.yml tasks: - name: Install Prerequisites apt: name=aptitude update_cache=yes state=latest force_apt_get=yes # Sudo Group Setup - name: Make sure we have a 'wheel' group group: name: wheel state: present - name: Allow 'wheel' group to have passwordless sudo lineinfile: path: /etc/sudoers state: present regexp: '^%wheel' line: '%wheel ALL=(ALL) NOPASSWD: ALL' validate: '/usr/sbin/visudo -cf %s' # User + Key Setup - name: Create a new regular user with sudo privileges user: name: "{{ create_user }}" state: present groups: wheel append: true create_home: true shell: /bin/bash - name: Set authorized key for remote user authorized_key: user: "{{ create_user }}" state: present key: "{{ copy_local_key }}" - name: Disable password authentication for root lineinfile: path: /etc/ssh/sshd_config state: present regexp: '^#?PermitRootLogin' line: 'PermitRootLogin prohibit-password' # Install Packages - name: Update apt apt: update_cache=yes - name: Install required system packages apt: name={{ sys_packages }} state=latest # UFW Setup - name: UFW - Allow SSH connections ufw: rule: allow name: OpenSSH - name: UFW - Deny all other incoming traffic by default ufw: state: enabled policy: deny direction: incoming
随意修改此手册或添加新任务,以在您自己的工作流程中最适合您的个人需求。
结论
自动化初始服务器设置可以节省您的时间,同时还可以确保您的服务器遵循可以根据您的需要进行改进和定制的标准配置。 由于现代应用程序的分布式特性以及不同暂存环境之间需要更高的一致性,这样的自动化成为必要。
在本指南中,我们演示了如何使用 Ansible 自动执行应在新服务器上执行的初始任务,例如创建具有 sudo 访问权限的非 root 用户、启用 UFW 和禁用基于密码的远程 root 登录。
如果您想在本手册中包含新任务以进一步自定义初始服务器设置,请参阅我们的 Ansible 入门指南 配置管理 101:编写 Ansible 手册。 您还可以查看我们关于 如何使用 Ansible 角色来抽象您的基础架构环境 的指南。