dcoker inspec
The author selected the Diversity in Tech Fund to receive a donation as part of the Write for DOnations program.
作者选择了“技术多元化”基金来接受捐赠,这是Write for DOnations计划的一部分。
介绍 (Introduction)
InSpec is an open-source auditing and automated testing framework used to describe and test for regulatory concerns, recommendations, or requirements. It is designed to be human-readable and platform-agnostic. Developers can work with InSpec locally or using SSH, WinRM, or Docker to run testing, so it’s unnecessary to install any packages on the infrastructure that is being tested.
InSpec是一个开放源代码审核和自动化测试框架,用于描述和测试法规问题,建议或要求。 它被设计为人类可读且与平台无关。 开发人员可以在本地使用InSpec或使用SSH,WinRM或Docker来运行测试,因此无需在正在测试的基础架构上安装任何软件包。
Although with InSpec you can run tests directly on your servers, there is a potential for human error that could cause issues in your infrastructure. To avoid this scenario, developers can use Kitchen to create a virtual machine and install an OS of their choice on the machines where tests are running. Kitchen is a test runner, or test automation tool, that allows you to test infrastructure code on one or more isolated platforms. It also supports many testing frameworks and is flexible with a driver plugin architecture for various platforms such as Vagrant, AWS, DigitalOcean, Docker, LXC containers, etc.
尽管使用InSpec可以直接在服务器上运行测试,但是可能存在人为错误,这可能会导致基础结构出现问题。 为避免这种情况,开发人员可以使用Kitchen创建虚拟机,并在运行测试的计算机上安装他们选择的操作系统。 Kitchen是一个测试运行程序或测试自动化工具,它使您可以在一个或多个隔离的平台上测试基础结构代码。 它还支持许多测试框架,并具有适用于各种平台(例如Vagrant,AWS,DigitalOcean,Docker,LXC容器等)的驱动程序插件体系结构 ,非常灵活。
In this tutorial, you’ll write tests for your Ansible playbooks running on a DigitalOcean Ubuntu 18.04 Droplet. You’ll use Kitchen as the test-runner and InSpec for writing the tests. By the end of this tutorial, you’ll be able to test your Ansible playbook deployment.
在本教程中,您将为在DigitalOcean Ubuntu 18.04 Droplet上运行的Ansible剧本编写测试。 您将使用Kitchen作为测试运行程序,并使用InSpec编写测试。 在本教程结束时,您将能够测试Ansible剧本的部署。
先决条件 (Prerequisites)
Before you begin with this guide, you’ll need a DigitalOcean account in addition to the following:
在开始本指南之前,除了以下内容之外,您还需要一个DigitalOcean帐户 :
A local installation of
Ruby
on your machine. You can install Ruby by following the tutorial for your distribution in the series: How To Install and Set Up a Local Programming Environment for Ruby.在计算机上本地安装
Ruby
。 您可以按照本系列中的发行教程来安装Ruby: 如何为Ruby安装和设置本地编程环境 。Chef Development Kit (ChefDK) installed on your machine.
您的计算机上安装了Chef开发套件(ChefDK) 。
SSH keys set up on your machine by following Steps 1 and 2 of How To Set Up SSH Keys. To upload your SSH public key to your DigitalOcean account you can follow our How To Add SSH Keys to a DigitalOcean Account tutorial.
遵循如何设置SSH密钥中的步骤1和2 在计算机上设置SSH密钥 。 要将SSH公钥上载到DigitalOcean帐户,您可以按照我们的“ 如何将SSH密钥添加到DigitalOcean帐户”教程中进行操作。
A read and write DigitalOcean personal access token. Make sure you record the token in a safe place; you’ll use it later in this tutorial. This allows you to create a Droplet on DigitalOcean, which is where this tutorial will run the tests.
读写DigitalOcean个人访问令牌 。 确保将令牌记录在安全的地方; 您将在本教程的后面部分中使用它。 这使您可以在DigitalOcean上创建一个Droplet,本教程将在其中运行测试。
步骤1 —设置和初始化厨房 (Step 1 — Setting Up and Initializing Kitchen)
You’ve installed ChefDK as part of the prerequisites that comes packaged with kitchen. In this step, you’ll set up Kitchen to communicate with DigitalOcean.
您已经安装ChefDK作为kitchen附带的前提条件的一部分。 在此步骤中,您将设置Kitchen与DigitalOcean通信。
Before initializing Kitchen, you’ll create and move into a project directory. In this tutorial, we’ll call it ansible_testing_dir
.
在初始化Kitchen之前,您将创建并移入项目目录。 在本教程中,我们将其ansible_testing_dir
。
Run the following command to create the directory:
运行以下命令创建目录:
mkdir ~/ansible_testing_dir
mkdir〜 / ansible_testing_dir
And then move into it:
然后进入它:
cd ~/ansible_testing_dir
cd〜 / ansible_testing_dir
Using gem
install the kitchen-digitalocean
package on your local machine. This allows you to tell kitchen
to use the DigitalOcean driver when running tests:
使用gem
将kitchen-digitalocean
软件包安装在本地计算机上。 这使您可以告诉kitchen
在运行测试时使用DigitalOcean驱动程序:
- gem install kitchen-digitalocean 宝石安装厨房-数字海洋
Within the project directory, you’ll run the kitchen init
command specifying ansible_playbook
as the provisioner and digitalocean
as the driver when initializing Kitchen:
在项目目录中,您将运行kitchen init
命令,在初始化Kitchen时将ansible_playbook
指定为ansible_playbook
,并指定digitalocean
作为驱动程序:
- kitchen init --provisioner=ansible_playbook --driver=digitalocean 厨房初始化--provisioner = ansible_playbook --driver = digitalocean
You’ll see the following output:
您将看到以下输出:
Output
create kitchen.yml
create chefignore
create test/integration/default
This has created the following within your project directory:
这在您的项目目录中创建了以下内容:
test/integration/default
is the directory to which you’ll save your test files.test/integration/default
是将测试文件保存到的目录。chefignore
is the file you would use to ensure certain files are not uploaded to the Chef Infra Server, but you won’t be using it in this tutorial.chefignore
是用于确保某些文件不会上载到Chef Infra Server的文件 ,但在本教程中不会使用它。kitchen.yml
is the file that describes your testing configuration: what you want to test and the target platforms.kitchen.yml
是描述您的测试配置的文件:您要测试的内容和目标平台。
Now, you need to export your DigitalOcean credentials as environment variables to have access to create Droplets from your CLI. First, start with your DigitalOcean access token by running the following command:
现在,您需要将DigitalOcean凭据导出为环境变量,才能访问从CLI创建Droplet的权限。 首先,通过运行以下命令从您的DigitalOcean访问令牌开始:
export DIGITALOCEAN_ACCESS_TOKEN="YOUR_DIGITALOCEAN_ACCESS_TOKEN"
export DIGITALOCEAN_ACCESS_TOKEN =“ YOUR_DIGITALOCEAN_ACCESS_TOKEN ”
You also need to get your SSH Key ID number; note that YOUR_DIGITALOCEAN_SSH_KEY_IDS
must be the numeric ID of your SSH key, not the symbolic name. Using the DigitalOcean API, you can get the numeric ID of your keys with the following command:
您还需要获取SSH密钥ID号; 请注意, YOUR_DIGITALOCEAN_SSH_KEY_IDS
必须是SSH密钥的数字ID,而不是符号名称。 使用DigitalOcean API,您可以通过以下命令获取密钥的数字ID:
- curl -X GET https://api.digitalocean.com/v2/account/keys -H "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN" curl -X GET https://api.digitalocean.com/v2/account/keys -H“授权:承载$ DIGITALOCEAN_ACCESS_TOKEN”
From this command you’ll see a list of your SSH Keys and related metadata. Read through the output to find the correct key and identify the ID number within the output:
通过此命令,您将看到SSH密钥和相关元数据的列表。 通读输出以找到正确的密钥并在输出中标识ID号:
Output
...
{"id":your-ID-number,"fingerprint":"fingerprint","public_key":"ssh-rsa your-ssh-key","name":"your-ssh-key-name"
...
Note: If you would like to make your output more readable to obtain your numeric IDs, you can find and download jq
based on your OS on the jq download page. Now, you can run the previous command piped into jq
as following:
注意:如果要使输出更具可读性以获取数字ID,可以在jq下载页面上根据您的操作系统找到并下载jq
。 现在,您可以运行通过管道jq
到jq
的先前命令,如下所示:
- curl -X GET https://api.digitalocean.com/v2/account/keys -H "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN" | jq curl -X GET https://api.digitalocean.com/v2/account/keys -H“授权:承载$ DIGITALOCEAN_ACCESS_TOKEN” | q
You’ll see your SSH Key information formatted similarly to:
您会看到SSH密钥信息的格式类似于:
Output
{
"ssh_keys": [
{
"id": YOUR_SSH_KEY_ID,
"fingerprint": "2f:d0:16:6b",
"public_key": "ssh-rsa AAAAB3NzaC1yc2 example@example.local",
"name": "sannikay"
}
],
}
Once you’ve identified your SSH numeric IDs, export them with the following command:
识别SSH数字ID后,请使用以下命令将其导出:
export DIGITALOCEAN_SSH_KEY_IDS="YOUR_DIGITALOCEAN_SSH_KEY_ID"
export DIGITALOCEAN_SSH_KEY_IDS =“ YOUR_DIGITALOCEAN_SSH_KEY_ID ”
You’ve initialized kitchen
and set up the environment variables for your DigitalOcean credentials. Now you’ll move on to create and run tests on your DigitalOcean Droplets directly from the command line.
您已经初始化kitchen
并为DigitalOcean凭据设置了环境变量。 现在,您将继续直接从命令行在DigitalOcean Droplet上创建并运行测试。
第2步-创建Ansible剧本 (Step 2 — Creating the Ansible Playbook)
In this step, you’ll create a playbook and roles that set up Nginx and Node.js on the Droplet created by kitchen
in the next step. Your tests will be run against the playbook to ensure the conditions specified in the playbook are met.
在此步骤中,您将创建一个剧本和角色 ,以在下一步由kitchen
创建的Droplet上设置Nginx和Node.js。 您将针对剧本进行测试,以确保满足剧本中指定的条件。
To begin, create a roles
directory for both the Nginx and Node.js roles:
首先,为Nginx和Node.js角色创建一个roles
目录:
- mkdir -p roles/{nginx,nodejs}/tasks mkdir -p角色/ {nginx,nodejs} /任务
This will create a directory structure as follows:
这将创建一个目录结构,如下所示:
roles
├── nginx
│ └── tasks
└── nodejs
└── tasks
Now, create a main.yml
file in the roles/nginx/tasks
directory using your preferred editor:
现在,使用您喜欢的编辑器在roles/nginx/tasks
目录中创建一个main.yml
文件:
- nano roles/nginx/tasks/main.yml 纳米角色/ nginx /任务/main.yml
In this file, create a task that sets up and starts Nginx by adding the following content:
在此文件中,通过添加以下内容来创建一个设置并启动Nginx的任务 :
---
- name: Update cache repositories and install Nginx
apt:
name: nginx
update_cache: yes
- name: Change nginx directory permission
file:
path: /etc/nginx/nginx.conf
mode: 0750
- name: start nginx
service:
name: nginx
state: started
Once you’ve added the content, save and exit the file.
添加内容后,保存并退出文件。
In roles/nginx/tasks/main.yml
, you define a task that will update the cache repository of your Droplet, which is an equivalent of running the apt update
command manually on a server. This task also changes the Nginx configuration file permissions and starts the Nginx service.
在roles/nginx/tasks/main.yml
,定义一个任务,该任务将更新Droplet的缓存存储库,这等效于在服务器上手动运行apt update
命令。 此任务还将更改Nginx配置文件权限,并启动Nginx服务。
You are also going to create a main.yml
file in roles/nodejs/tasks
to define a task that sets up Node.js:
您还将在roles/nodejs/tasks
创建一个main.yml
文件,以定义一个设置Node.js的任务:
- nano roles/nodejs/tasks/main.yml 纳米角色/nodejs/tasks/main.yml
Add the following tasks to this file:
将以下任务添加到该文件:
---
- name: Update caches repository
apt:
update_cache: yes
- name: Add gpg key for NodeJS LTS
apt_key:
url: "https://deb.nodesource.com/gpgkey/nodesource.gpg.key"
state: present
- name: Add the NodeJS LTS repo
apt_repository:
repo: "deb https://deb.nodesource.com/node_{{ NODEJS_VERSION }}.x {{ ansible_distribution_release }} main"
state: present
update_cache: yes
- name: Install Node.js
apt:
name: nodejs
state: present
Save and exit the file when you’re finished.
完成后保存并退出文件。
In roles/nodejs/tasks/main.yml
, you first define a task that will update the cache repository of your Droplet. Then with the next task you add the GPG key for Node.js that serves as a means of verifying the authenticity of the Node.js apt
repository. The final two tasks add the Node.js apt
repository and install Node.js.
首先,在roles/nodejs/tasks/main.yml
,定义一个任务,该任务将更新Droplet的缓存存储库。 然后,在下一个任务中,添加Node.js的GPG密钥,该密钥用作验证Node.js apt
存储库真实性的一种方法。 最后两个任务将添加Node.js apt
存储库并安装Node.js。
Now you’ll define your Ansible configurations, such as variables, the order in which you want your roles to run, and super user privilege settings. To do this, you’ll create a file named playbook.yml
, which serves as an entry point for Kitchen. When you run your tests, Kitchen starts from your playbook.yml
file and looks for the roles to run, which are your roles/nginx/tasks/main.yml
and roles/nodejs/tasks/main.yml
files.
现在,您将定义Ansible配置,例如变量,您希望角色运行的顺序以及超级用户特权设置。 为此,您将创建一个名为playbook.yml
的文件,该文件用作Kitchen的入口点。 运行测试时,Kitchen从playbook.yml
文件开始,并寻找要运行的角色,即您的roles/nginx/tasks/main.yml
和roles/nodejs/tasks/main.yml
文件。
Run the following command to create playbook.yml
:
运行以下命令来创建playbook.yml
:
- nano playbook.yml 纳米playbook.yml
Add the following content to the file:
将以下内容添加到文件中:
---
- hosts: all
become: true
remote_user: ubuntu
vars:
NODEJS_VERSION: 8
Save and exit the file.
保存并退出文件。
You’ve created the Ansible playbook roles that you’ll be running your tests against to ensure conditions specified in the playbook are met.
您已经创建了Ansible剧本角色,将用来运行测试以确保满足剧本中指定的条件。
第3步-编写InSpec测试 (Step 3 — Writing Your InSpec Tests)
In this step, you’ll write tests to check if Node.js is installed on your Droplet. Before writing your test, let’s look at the format of an example InSpec test. As with many test frameworks, InSpec code resembles a natural language. InSpec has two main components, the subject to examine and the subject’s expected state:
在此步骤中,您将编写测试以检查Droplet上是否安装了Node.js。 在编写测试之前,让我们看一下示例InSpec测试的格式。 与许多测试框架一样,InSpec代码类似于自然语言。 InSpec具有两个主要组成部分,即要检查的主题和该主题的预期状态:
describe '<entity>' do
it { <expectation> }
end
In block A, the keywords do
and end
define a block
. The describe
keyword is commonly known as test suites, which contain test cases. The it
keyword is used for defining the test cases.
在块A中,关键字do
和end
定义了一个block
。 describe
关键字通常称为测试套件,其中包含测试用例。 it
关键字用于定义测试用例。
<entity>
is the subject you want to examine, for example, a package name, service, file, or network port. The <expectation>
specifies the desired result or expected state, for example, Nginx should be installed or should have a specific version. You can check the InSpec DSL documentation to learn more about the InSpec language.
<entity>
是您要检查的主题,例如,程序包名称,服务,文件或网络端口。 <expectation>
指定所需的结果或预期的状态,例如,应安装Nginx或具有特定版本。 您可以查看InSpec DSL文档以了解有关InSpec语言的更多信息。
Another example InSpec test block:
InSpec测试块的另一个示例:
control 'Can be anything unique' do
impact 0.7
title 'A human-readable title'
desc 'An optional description'
describe '<entity>' do
it { <expectation> }
end
end
The difference between block A and block B is the control
block. The control
block is used as a means of regulatory control, recommendation or requirement. The control
block has a name; usually a unique ID, metadata such as desc
, title
, impact
, and finally group together related describe
block to implement the checks.
块A和块B之间的区别是control
块。 control
块用作监管控制,建议或要求的手段。 control
块有一个名称; 通常是唯一ID,元数据(例如desc
, title
, impact
,最后将相关的describe
分组在一起)以实施检查。
desc
, title
, and impact
define metadata that fully describe the importance of the control, its purpose, with a succinct and complete description. impact
defines a numeric value that ranges from 0.0
to 1.0
where 0.0
to <0.01
is classified as no impact, 0.01
to <0.4
is classified as low impact, 0.4
to <0.7
is classified as medium impact, 0.7
to <0.9
is classified as high impact, 0.9
to 1.0
is classified as critical control.
desc
, title
和impact
定义了元数据,该元数据以简洁而完整的描述充分描述了控件的重要性及其目的。 impact
定义的数值范围为0.0
到1.0
,其中0.0
到<0.01
被分类为无冲击, 0.01
到<0.4
被分类为低冲击, 0.4
到<0.7
被分类为中等冲击, 0.7
到<0.9
被分类为高冲击影响为0.9
到1.0
列为关键控制。
Now to implement a test. Using the syntax of block A, you’ll use InSpec’s package
resource to test if Node.js
is installed on the system. You’ll create a file named sample.rb
in your test/integration/default
directory for your tests.
现在实施测试。 使用块A的语法,你会使用INSPEC的package
,如果资源测试Node.js
已经安装在系统上。 您将在test/integration/default
目录中为测试创建一个名为sample.rb
的文件。
Create sample.rb
:
创建sample.rb
:
- nano test/integration/default/sample.rb 纳米测试/集成/默认/sample.rb
Add the following to your file:
将以下内容添加到您的文件中:
describe package('nodejs') do
it { should be_installed }
end
Here your test is using the package
resource to check Node.js is installed.
在这里,您的测试使用package
资源来检查是否已安装Node.js。
Save and exit the file when you’re finished.
完成后保存并退出文件。
To run this test, you need to edit kitchen.yml
to specify the playbook you created earlier and to add to your configurations.
要运行此测试,您需要编辑kitchen.yml
以指定您之前创建的剧本并添加到您的配置中。
Open your kitchen.yml
file:
打开您的kitchen.yml
文件:
- nano ansible_testing_dir/kitchen.yml 纳米ansible_testing_dir / kitchen.yml
Replace the content of kitchen.yml
with the following:
用以下内容替换kitchen.yml
的内容:
---
driver:
name: digitalocean
provisioner:
name: ansible_playbook
hosts: test-kitchen
playbook: ./playbook.yml
verifier:
name: inspec
platforms:
- name: ubuntu-18
driver_config:
ssh_key: PATH_TO_YOUR_PRIVATE_SSH_KEY
tags:
- inspec-testing
region: fra1
size: 1gb
private_networking: false
verifier:
inspec_tests:
- test/integration/default
suites:
- name: default
The platform
options include the following:
platform
选项包括:
name
: The image you’re using.name
:您正在使用的图像。driver_config
: Your DigitalOcean Droplet configuration. You’re specifying the following options for thedriver_config
:driver_config
:您的DigitalOcean Droplet配置。 您要为driver_config
指定以下选项:ssh_key
: Path toYOUR_PRIVATE_SSH_KEY
. YourYOUR_PRIVATE_SSH_KEY
is located in the directory you specified when creating yourssh
key.ssh_key
:路径YOUR_PRIVATE_SSH_KEY
。 您的YOUR_PRIVATE_SSH_KEY
位于创建ssh
密钥时指定的目录中。tags
: The tags associated with your Droplet.tags
:与您的Droplet相关的标签。region
: Theregion
where you want your Droplet to be hosted.region
:您希望托管Droplet的region
。size
: The memory you want your Droplet to have.size
:您希望Droplet拥有的内存。
verifier
: This defines that the project contains InSpec tests.verifier
:定义项目包含InSpec测试。The
inspec_tests
part specifies that the tests exist under the projecttest/integration/default
directory.inspec_tests
部分指定测试存在于项目test/integration/default
目录下。
Note that the name
and region
use abbreviations. You can check on the test-kitchen
documentation for the abbreviations you can use.
请注意, name
和region
使用缩写。 您可以在test-kitchen
文档中查看可以使用的缩写。
Once you’ve added your configuration, save and exit the file.
添加配置后,保存并退出文件。
Run the kitchen test
command to run the test. This will check to see if Node.js is installed—this will purposefully fail because you don’t currently have the Node.js role in your playbook.yml
file:
运行kitchen test
命令以运行测试。 这将检查是否已安装Node.js,这将有意失败,因为您当前在playbook.yml
文件中没有Node.js角色:
- kitchen test 厨房测试
You’ll see output similar to the following:
您将看到类似于以下内容的输出:
Output: failing test results
-----> Starting Kitchen (v1.24.0)
-----> Cleaning up any prior instances of <default-ubuntu-18>
-----> Destroying <default-ubuntu-18>...
DigitalOcean instance <145268853> destroyed.
Finished destroying <default-ubuntu-18> (0m2.63s).
-----> Testing <default-ubuntu-18>
-----> Creating <default-ubuntu-18>...
DigitalOcean instance <145273424> created.
Waiting for SSH service on 138.68.97.146:22, retrying in 3 seconds
[SSH] Established
(ssh ready)
Finished creating <default-ubuntu-18> (0m51.74s).
-----> Converging <default-ubuntu-18>...
$$$$$$ Running legacy converge for 'Digitalocean' Driver
-----> Installing Chef Omnibus to install busser to run tests
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Downloading files from <default-ubuntu-18>
Finished converging <default-ubuntu-18> (0m55.05s).
-----> Setting up <default-ubuntu-18>...
$$$$$$ Running legacy setup for 'Digitalocean' Driver
Finished setting up <default-ubuntu-18> (0m0.00s).
-----> Verifying <default-ubuntu-18>...
Loaded tests from {:path=>". ansible_testing_dir.test.integration.default"}
Profile: tests from {:path=>"ansible_testing_dir/test/integration/default"} (tests from {:path=>"ansible_testing_dir.test.integration.default"})
Version: (not specified)
Target: ssh://root@138.68.97.146:22
System Package nodejs
× should be installed
expected that System Package nodejs is installed
Test Summary: 0 successful, 1 failure, 0 skipped
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: 1 actions failed.
>>>>>> Verify failed on instance <default-ubuntu-18>. Please see .kitchen/logs/default-ubuntu-18.log for more details
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration
4.54s user 1.77s system 5% cpu 2:02.33 total
The output notes that your test is failing because you don’t have Node.js installed on the Droplet you provisioned with kitchen
. You’ll fix your test by adding the nodejs
role to your playbook.yml
file and run the test again.
输出结果表明您的测试失败,因为您没有在使用kitchen
设置的Droplet上安装Node.js。 您可以通过将nodejs
角色添加到playbook.yml
文件中来修复测试,然后再次运行测试。
Edit the playbook.yml
file to include the nodejs
role:
编辑playbook.yml
文件以包含nodejs
角色:
- nano playbook.yml 纳米playbook.yml
Add the following highlighted lines to your file:
将以下突出显示的行添加到您的文件中:
---
- hosts: all
become: true
remote_user: ubuntu
vars:
NODEJS_VERSION: 8
roles:
- nodejs
Save and close the file.
保存并关闭文件。
Now, you’ll rerun the test using the kitchen test
command:
现在,您将使用kitchen test
命令重新运行kitchen test
:
- kitchen test 厨房测试
You’ll see the following output:
您将看到以下输出:
Output
......
Target: ssh://root@46.101.248.71:22
System Package nodejs
✔ should be installed
Test Summary: 1 successful, 0 failures, 0 skipped
Finished verifying <default-ubuntu-18> (0m4.89s).
-----> Destroying <default-ubuntu-18>...
DigitalOcean instance <145512952> destroyed.
Finished destroying <default-ubuntu-18> (0m2.23s).
Finished testing <default-ubuntu-18> (2m49.78s).
-----> Kitchen is finished. (2m55.14s)
4.86s user 1.77s system 3% cpu 2:56.58 total
Your test now passes because you have Node.js installed using the nodejs
role.
现在您的测试通过了,因为您已经使用nodejs
角色安装了nodejs
Here is a summary of what Kitchen is doing in the Test Action
:
这是Kitchen在“ Test Action
所做的摘要:
- Destroys the Droplet if it exists 摧毁Droplet(如果存在)
- Creates the Droplet 创建液滴
- Converges the Droplet 汇聚液滴
- Verifies the Droplet with InSpec 使用InSpec验证液滴
- Destroys the Droplet 摧毁水滴
Kitchen will abort the run on your Droplet if it encounters any issues. This means if your Ansible playbook fails, InSpec won’t run and your Droplet won’t be destroyed. This gives you a chance to inspect the state of the instance and fix any issues. The behavior of the final destroy action can be overridden if desired. Check out the CLI help for the --destroy
flag by running the kitchen help test
command.
如果遇到任何问题,Kitchen将中止您Droplet的运行。 这意味着,如果您的Ansible剧本失败,则InSpec将不会运行,并且Droplet也不会被销毁。 这使您有机会检查实例的状态并解决所有问题。 如果需要,可以取消最终销毁操作的行为。 通过运行kitchen help test
命令来检查--destroy
标志的CLI帮助。
You’ve written your first tests and run them against your playbook with one instance failing before fixing the issue. Next you’ll extend your test file.
您已编写了第一个测试,并针对您的剧本进行了测试,但有一个实例失败,然后修复了问题。 接下来,您将扩展测试文件。
步骤4 —添加测试用例 (Step 4 — Adding Test Cases)
In this step, you’ll add more test cases to your test file to check if Nginx modules are installed on your Droplet and the configuration file has the right permissions.
在此步骤中,您将向测试文件中添加更多测试用例,以检查是否在Droplet上安装了Nginx模块,并且配置文件具有正确的权限。
Edit your sample.rb
file to add more test cases:
编辑您的sample.rb
文件以添加更多测试用例:
- nano test/integration/default/sample.rb 纳米测试/集成/默认/sample.rb
Add the following test cases to the end of the file:
将以下测试用例添加到文件末尾:
. . .
control 'nginx-modules' do
impact 1.0
title 'NGINX modules'
desc 'The required NGINX modules should be installed.'
describe nginx do
its('modules') { should include 'http_ssl' }
its('modules') { should include 'stream_ssl' }
its('modules') { should include 'mail_ssl' }
end
end
control 'nginx-conf' do
impact 1.0
title 'NGINX configuration'
desc 'The NGINX config file should owned by root, be writable only by owner, and not writeable or and readable by others.'
describe file('/etc/nginx/nginx.conf') do
it { should be_owned_by 'root' }
it { should be_grouped_into 'root' }
it { should_not be_readable.by('others') }
it { should_not be_writable.by('others') }
it { should_not be_executable.by('others') }
end
end
These test cases check that the nginx-modules
on your Droplet include http_ssl
, stream_ssl
, and mail_ssl
. You are also checking for /etc/nginx/nginx.conf
file permissions.
这些测试案例检查您Droplet上的nginx-modules
是否包含http_ssl
, stream_ssl
和mail_ssl
。 您还要检查/etc/nginx/nginx.conf
文件的权限。
You are using both the it
and its
keywords to define your test. The keyword its
is only used to access properties of the resources. For example, modules
is a property of nginx
.
您同时使用it
its
关键字来定义测试。 关键字its
仅用于访问资源的属性。 例如, modules
是nginx
的属性。
Save and exit the file once you’ve added the test cases.
添加测试用例后,保存并退出文件。
Now run the kitchen test
command to test again:
现在运行kitchen test
命令再次进行测试:
- kitchen test 厨房测试
You’ll see the following output:
您将看到以下输出:
Output
...
Target: ssh://root@104.248.131.111:22
↺ nginx-modules: NGINX modules
↺ The `nginx` binary not found in the path provided.
× nginx-conf: NGINX configuration (2 failed)
× File /etc/nginx/nginx.conf should be owned by "root"
expected `File /etc/nginx/nginx.conf.owned_by?("root")` to return true, got false
× File /etc/nginx/nginx.conf should be grouped into "root"
expected `File /etc/nginx/nginx.conf.grouped_into?("root")` to return true, got false
✔ File /etc/nginx/nginx.conf should not be readable by others
✔ File /etc/nginx/nginx.conf should not be writable by others
✔ File /etc/nginx/nginx.conf should not be executable by others
System Package nodejs
✔ should be installed
Profile Summary: 0 successful controls, 1 control failure, 1 control skipped
Test Summary: 4 successful, 2 failures, 1 skipped
You’ll see that some of the tests are failing. You’re going to fix those by adding the nginx
role to your playbook file and rerunning the test. In the failing test, you’re checking for nginx
modules and file permissions that are currently not present on your server.
您会看到某些测试失败。 您将通过在您的剧本文件中添加nginx
角色并重新运行测试来解决这些问题。 在失败的测试中,您正在检查服务器上当前不存在的nginx
模块和文件权限。
Open your playbook.yml
file:
打开您的playbook.yml
文件:
- nano ansible_testing_dir/playbook.yml 纳米ansible_testing_dir / playbook.yml
Add the following highlighted line to your roles:
将以下突出显示的行添加到您的角色:
---
- hosts: all
become: true
remote_user: ubuntu
vars:
NODEJS_VERSION: 8
roles:
- nodejs
- nginx
Save and close the file when you’re finished.
完成后保存并关闭文件。
Then run your tests again:
然后再次运行测试:
- kitchen test 厨房测试
You’ll see the following output:
您将看到以下输出:
Output
...
Target: ssh://root@104.248.131.111:22
✔ nginx-modules: NGINX version
✔ Nginx Environment modules should include "http_ssl"
✔ Nginx Environment modules should include "stream_ssl"
✔ Nginx Environment modules should include "mail_ssl"
✔ nginx-conf: NGINX configuration
✔ File /etc/nginx/nginx.conf should be owned by "root"
✔ File /etc/nginx/nginx.conf should be grouped into "root"
✔ File /etc/nginx/nginx.conf should not be readable by others
✔ File /etc/nginx/nginx.conf should not be writable by others
✔ File /etc/nginx/nginx.conf should not be executable by others
System Package nodejs
✔ should be installed
Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped
Test Summary: 9 successful, 0 failures, 0 skipped
After adding the nginx
role to the playbook all your tests now pass. The output shows that the http_ssl
, stream_ssl
, and mail_ssl
modules are installed on your Droplet and the right permissions are set for the configuration file.
在将nginx
角色添加到剧本之后,您的所有测试现在都通过了。 输出显示在您的Droplet上安装了http_ssl
, stream_ssl
和mail_ssl
模块,并为配置文件设置了正确的权限。
Once you’re finished, or you no longer need your Droplet, you can destroy it by running the kitchen destroy
command to delete it after running your tests:
完成操作后,或者不再需要Droplet时,可以在运行测试后通过运行kitchen destroy
命令删除它来删除它:
- kitchen destroy 厨房破坏
Following this command you’ll see output similar to:
执行此命令后,您将看到类似于以下内容的输出:
Output
-----> Starting Kitchen (v1.24.0)
-----> Destroying <default-ubuntu-18>...
Finished destroying <default-ubuntu-18> (0m0.00s).
-----> Kitchen is finished. (0m5.07s)
3.79s user 1.50s system 82% cpu 6.432 total
You’ve written tests for your playbook, run the tests, and fixed the failing tests to ensure all the tests are passing. You’re now set up to create a virtual environment, write tests for your Ansible Playbook, and run your test on the virtual environment using Kitchen.
您已经为剧本编写了测试,运行了测试,并修复了失败的测试,以确保所有测试都通过。 现在,您已设置为创建虚拟环境,为Ansible Playbook编写测试,并使用Kitchen在虚拟环境上运行测试。
结论 (Conclusion)
You now have a flexible foundation for testing your Ansible deployment, which allows you to test your playbooks before running on a live server. You can also package your test into a profile. You can use profiles to share your test through Github or the Chef Supermarket and easily run it on a live server.
现在,您具有测试Ansible部署的灵活基础,可以在运行实时服务器上之前测试剧本。 您也可以将测试打包到配置文件中 。 您可以使用配置文件通过Github或Chef Supermarket共享测试,并轻松地在实时服务器上运行它。
For more comprehensive details on InSpec and Kitchen, refer to the official InSpec documentation and the official Kitchen documentation.
有关InSpec和Kitchen的更全面的详细信息,请参考InSpec官方文档和Kitchen官方文档 。
dcoker inspec