当前位置: 首页 > 工具软件 > InSpec > 使用案例 >

dcoker inspec_如何使用InSpec和Kitchen测试您的Ansible部署

笪昌翰
2023-12-01

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帐户

步骤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:

使用gemkitchen-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 。 现在,您可以运行通过管道jqjq的先前命令,如下所示:

  • 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的任务

roles/nginx/tasks/main.yml
角色/ nginx /任务/main.yml
---
- 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:

将以下任务添加到该文件:

roles/nodejs/tasks/main.yml
角色/ nodejs /任务/main.yml
---
- 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.ymlroles/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:

将以下内容添加到文件中:

ansible_testing_dir/playbook.yml
ansible_testing_dir / playbook.yml
---
 - 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具有两个主要组成部分,即要检查的主题和该主题的预期状态:

block A
A座
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中,关键字doend定义了一个blockdescribe关键字通常称为测试套件,其中包含测试用例。 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测试块的另一个示例:

block B
B座
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,元数据(例如desctitleimpact ,最后将相关的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.

desctitleimpact定义了元数据,该元数据以简洁而完整的描述充分描述了控件的重要性及其目的。 impact定义的数值范围为0.01.0 ,其中0.0<0.01被分类为无冲击, 0.01<0.4被分类为低冲击, 0.4<0.7被分类为中等冲击, 0.7<0.9被分类为高冲击影响为0.91.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:

将以下内容添加到您的文件中:

test/integration/default/sample.rb
测试/集成/默认/ sample.rb
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的内容:

ansible_testing_dir/kitchen.yml
ansible_testing_dir / 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 the driver_config:

    driver_config :您的DigitalOcean Droplet配置。 您要为driver_config指定以下选项:

    • ssh_key: Path to YOUR_PRIVATE_SSH_KEY. Your YOUR_PRIVATE_SSH_KEY is located in the directory you specified when creating your ssh key.

      ssh_key :路径YOUR_PRIVATE_SSH_KEY 。 您的YOUR_PRIVATE_SSH_KEY位于创建ssh密钥时指定的目录中。

    • tags: The tags associated with your Droplet.

      tags :与您的Droplet相关的标签。

    • region: The region 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 project test/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.

请注意, nameregion使用缩写。 您可以在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:

将以下突出显示的行添加到您的文件中:

ansible_testing_dir/playbook.yml
ansible_testing_dir / playbook.yml
---
 - 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:

将以下测试用例添加到文件末尾:

test/integration/default/sample.rb
测试/集成/默认/ sample.rb
. . .
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_sslstream_sslmail_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仅用于访问资源的属性。 例如, modulesnginx的属性。

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:

将以下突出显示的行添加到您的角色:

ansible_testing_dir/playbook.yml
ansible_testing_dir / playbook.yml
---
- 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_sslstream_sslmail_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官方文档

翻译自: https://www.digitalocean.com/community/tutorials/how-to-test-your-ansible-deployment-with-inspec-and-kitchen

dcoker inspec

 类似资料: