inspec/docs/glossary.md
Unknown 5c1467dfe9 Update software name from InSpec to Chef Inspec
Signed-off-by: IanMadd <maddaus@protonmail.com>
2019-04-29 15:16:56 -04:00

21 KiB

Chef InSpec Glossary

This document should help you become familiar with some of the terminology used by the Chef InSpec project.

There are two ways to use it:

  • A text glossary. Learn the meaning of a word you have encountered.
  • A visual glossary. Look at examples and see how the parts are labelled. You can then use the text glossary to read details of each concept.

Visual Glossary

Motivating Example

Suppose we are interested in auditing cars. Let's suppose we have two Chef InSpec resources for auditing: cars, which searches for and filters groups of cars, and car, which performs detailed auditing of a single car.

Basic Syntax

Let's look at some simple examples.

Singular Resource Example

describe car(owner: 'Tony Clifton') do
    it { should exist }
    its('license_plate') { should cmp 'MOONMAN' }
    it { should be_classy }
    it { should_not have_check_engine_light_on }
end

describe car(owner: 'Tony Clifton') do

car is a resource. Since we are talking about only one car, it is a singular resource.

describe car(owner: 'Tony Clifton')

owner is a resource parameter and 'Tony Clifton' is a resource parameter value.

it { should exist }

Each line within the resource block beginning with it or its is a test. Use it to access resource-specific matchers, and use its to access properties of the resource, which are in turn used with universal matchers.

its('license_plate') { should cmp 'MOONMAN' }

license_plate is a property belonging to the resource. Properties expose testable information about the resource. Some properties are numbers, some (like this one) are text, some are lists, and some are more complex objects. Properties are always used with universal matchers.

its('license_plate') { should cmp 'MOONMAN' }

cmp is a universal matcher. cmp is a very flexible, loosely typed equality operator; here it checks to see if the license plate text is the same as the text 'MOONMAN'. Notice that the test operates on the license plate text (the property value) and not on the resource. You can find the full list of supported universal matchers on the Universal Matcher page.

its('license_plate') { should cmp 'MOONMAN' }

'MOONMAN' is an expected result. Some matchers take an expected result; others do not.

it { should be_classy }

be_classy is a resource-specific matcher. It returns a yes-or-no value, based on whether Tony's car is classy or not. (It is. Tony is a classy guy.)

it { should_not have_check_engine_light_on }

should_not indicates this is a negated test. So, this test passes if the matcher says "no".

Plural Resource Example

  describe cars.where(color: /^b/) do
    it { should exist }
    its('manufacturers') { should include 'Cadillac' }
    its('count') { should be >= 10 }
  end

describe cars.where(color: /^b/) do

cars is a resource. Since we are potentially talking about many cars, it is a plural resource.

describe cars.where(color: /^b/) do

where(color: /^b/) is a filter statement. Without a filter statement, cars simply selects all the cars in the world.

describe cars.where(color: /^b/) do

color is a filter criterion along with its filter value, /^b/. Here, the criterion expresses that we want to select all cars whose colors begin with the letter 'b' - blue, brown, burgundy, etc.

it { should exist }

Each line within the resource block beginning with it or its is a test. Use it to access resource-specific matchers, and use its to access properties of the resource, which are in turn used with universal matchers.

With plural resources, exist has a special meaning: did the filter match anything?

its('manufacturers') { should include 'Cadillac' }

manufacturers is a property of the resource. Properties expose testable information about the resource. On plural resources, properties are almost always names in the plural, and almost always return a list of values. Here, the test returns a list of the car manufacturer names. Some list properties are de-duplicated; for example, you might have 10 cars, but if they are all Subarus and Cadillacs, it returns only two entries in the manufacturers property. Be sure to check the documentation for your resource.

its('manufacturers') { should include 'Cadillac' }

include is a universal matcher. include works with lists, and checks to see if an expected result is present. Here, it checks to see if the list of manufacturers contains an entry with the text 'Cadillac'. Notice it operates on the manufacturers list (the property value) and not on the resource. You can find the full list of supported universal matchers on the Universal Matcher page.

its('manufacturers') { should include 'Cadillac' }

'Cadillac' is an expected result. Some matchers take an expected result; others do not.

its('count') { should be >= 10 }

be >= is an [operator matcher](#operator matcher). It allows you to perform numeric comparisons. All plural resources have a count property.

Text Glossary

attribute

An attribute is a parameter that Chef InSpec reads from a YAML file provided on the command line. You can use this feature either to change a profile's behavior by passing different attribute files or to store secrets that should not be directly present in a profile. Chef InSpec attributes are unrelated to Chef attributes.

The CLI syntax for attributes is documented under the inspec exec command.

The syntax for accessing attributes within a profile is documented in the profiles documentation.

control

control block

The control keyword is used to declare a control block. Here, the word 'control' means a 'regulatory control, recommendation, or requirement' - not a software engineering construct. A control block has a name (which usually refers to the assigned ID of the regulatory recommendation it implements), metadata such as descriptions, references, and tags, and finally groups together related describe blocks to implement the checks.

core resource

A resource that is included with InSpec; you are not required to install additional plugins or depend on a [resource pack](#resource pack) to use the resource.

custom resource

A resource that is not included with InSpec. It may be a resource of your own creation, or one you obtain by depending on a [resource pack](#resource pack).

describe

describe block

The describe keyword is used with a describe block to refer to an Chef InSpec resource. You use the describe keyword along with the name of a resource to enclose related tests that apply to the resource. Multiple describe blocks are usually grouped together in a control, but you can also use them outside of a control.

control 'Rule 1.1 - Color restrictions' do
  # Count only blue cars
  describe cars.where(color: 'blue') do
    its('count') { should eq 20 }
  end
end

DSL

DSL is an acronym for Domain Specific Language. It refers to the language extensions Chef InSpec provides to make authoring resources and controls easier. While Chef InSpec control files are use Ruby, the Control DSL makes it easy to write controls without knowledge of Ruby by providing DSL keywords such as describe, control, it and its. See the Chef InSpec DSL page for details about keywords available to control authors.

For custom resource authors, an additional DSL is available - see the Resource DSL page.

expected result

When using a matcher, the expected result is the value the matcher will compare against the property being accessed.

In this example, the cmp matcher is being used to compare the color property to the expected result 'black'.

describe car(owner: 'Bruce Wayne') do
  its('color') { should cmp 'black' }
end

filter statement

When using a plural resource, a filter statement is used to select individual test subjects using filter criteria. A filter statement almost always is indicated by the keyword where, and may be repeated using method chaining.

A filter statement may use method call syntax (which allows basic criteria operations, such as equality, regex matching, and ruby === comparison) or block syntax (which allows arbitrary code).

In this example, where(...) is the filter statement.

# Count only blue cars
describe cars.where(color: 'blue') do
  its('count') { should eq 20 }
end

filter criterion

filter criteria

When using a plural resource, a filter criterion is used to select individual test subjects within a filter statement. You may use multiple filter criteria in a single filter statement.

When method-call syntax is used with the filter statement, you provide filter criteria as a Hash, with filter criteria names as keys, and conditions as the Hash values. You may provide test, true/false, or numbers, in which case the comparison is equality; or you may provide a regular expression, in which case a match is performed.

Here, (color: blue) is a single filter criterion being used with a filter statement in method-call syntax.

# Count only blue cars
describe cars.where(color: 'blue') do
  its('count') { should eq 20 }
end

When block-method syntax is used with the filter statement, you provide a block. The block may contain arbitrary code, and each filter criteria will be available as an accessor. The block will be evaluated once per row, and each block that evaluates to a truthy value will pass the filter.

Here, { engine_cylinders >= 6 } is a block-syntax filter statement referring to one filter criterion.

# Vroom!
describe cars.where { engine_cylinders >= 6 } do
  its('city_mpg_ratings') { should_not include '4-star' }
end

it

Within a describe block, it declares an individual test directly against the resource (as opposed to testing against one of the resource's properties, as its does). Though it is possible to use universal matchers with it, it is much more typical to use resource-specific matchers.

it may be used with should, or negated using should_not.

Here, it { should ... } declares a test, calling the classy? matcher on Tony Clifton's car.

describe car(owner: 'Tony Clifton') do
  it { should be_classy }
end

its

Within a describe block, its declares an individual test against a property of the resource (as opposed to testing directly against the resource itself, as it does). You must use universal matchers with its; you cannot use resource-specific matchers.

its may be used with should, or negated using should_not.

The property to access is passed as a single string argument to its. As an advanced usage, if the property has methods you are interested in, you can call them using '.' within the string; even more advanced calling patterns are possible - see the rspec-its documentation.

Here, its('fuzzy_dice') { should ... } declares a test, testing against the fuzzy_dice property of Tony Clifton's car. Let's assume - Tony being Tony - that fuzzy_dice will return an Array.

describe car(owner: 'Tony Clifton') do
  its('fuzzy_dice') { should_not be_empty }
  its('fuzzy_dice.count') { should be >= 2 }
  its('fuzzy_dice.first.fuzziness') { should cmp 'outlandishly so' }
end

matcher

A matcher performs the actual assertions against resources or the properties of resources. Matchers always return a true/false value. Matchers fall into two camps:

  • resource-specific matchers, which operate directly on the resource, are used with it, and tend to be highly customized to the auditing needs of the resource
  • universal matchers, which operate on the properties of the resource, are used with its, and tend to be very generic, operating on text, numbers, and lists

Some matchers accept parameters, called expected results.

For information on how RSpec matchers are related o Chef InSpec matchers, see Chef InSpec and RSpec.

Here, be_classy is a resource-specific matcher operating directly on the car, while cmp is a universal matcher operating on the manufacturer property.

describe car(owner: 'Tony Clifton') do
  it { should be_classy }
  its('manufacturer') { should cmp 'Cadillac' }
end

plural resource

A plural resource is a resource that specializes in performing searches and represents multiple occurrences of the resource on the target platform. Plural resources are used to audit counts, inspect group properties, and have the unique ability to enforce negative tests ("nothing like this should exist") often required by compliance standards. Plural resources are not intended to perform in-depth auditing of an individual; use singular resources for that.

Plural resources nearly always have a name that ends in 's': processes, aws_security_groups, cars. Plural resources generally do not have resource-specific matchers. If they have properties, they are almost always list properties, meaning that they return a list of values, which may or may not be de-duplicated.

Plural resources support filter statements. See the resource documentation for details regarding which filter criteria are supported on each resource.

Here, cars is a plural resource.

describe cars.where(color: 'blue') do
  its('count') { should eq 20 }
  its('license_plates') { should include 'AUTOAZUL' }

  # License plates are unique, should have 20
  its('license_plates.count') { should cmp 20 }

  # Manufacturers are de-duplicated
  its('manufacturers') { should include 'Subaru' }
  its('manufacturers.count') { should be < 10 }
end

profile

A profile is a set of related controls in a distributable form. You might have a locally-developed profile that your organization uses to define baseline security on all machines, or you might use a pre-defined profile that implements the requirements of a specific compliance standard. For full details about the capabilities of a profile, see the profile documentation.

Profiles may be distributed locally as a directory tree, as a tarball or zipfile at a URL, as a git repo, and several other ways. Profiles contain metadata, including versioning, and can setup dependency relationships with other profiles.

Aside from controls, profiles can also contain custom resources. If the profile contains only custom resources and no controls, we call it a resource pack.

property

A fact about a resource. Typically, you use the its keyword to access the property and write a test within a describe block, and then use a universal matcher to make assertions about the value of the property.

Each resource has different properties. See the resource documentation for details.

Here, manufacturer is a property of the car resource.

describe car(owner: 'Tony Clifton') do
  its('manufacturer') { should cmp 'Cadillac' }
end

reporter

An output format for the inspec exec command line. Several reporters are available, including JSON and JUnit; see the inspec exec documentation.

resource

A resource represents a category of things on the target you wish to examine. For example, to check for the existence and permissions of a file, you would use the file resource. Chef InSpec offers dozens of different resources, from the highly specialized (such as aws_security_group, which examines firewall rules in AWS) to the very general (such as command, which runs a command and lets you examine its output).

Resources are generally categorized as either singular or plural, though there are some irregular resources that cannot be cleanly considered one or the other.

Resources are used within a describe block to perform tests.

Here, car is a resource.

describe car(owner: 'Tony Clifton') do
  it { should be_classy }
end

resource pack

A resource pack is a type of profile that is used to distribute custom resources. This specialized type of profile contains no controls, but it does contain a libraries directory within which Ruby files define custom resources.

resource parameter

resource parameters are information passed to the resource when they are declared. Typically, resource parameters provide identifying information or connectivity information. Resource parameters are not the same as a filter statement.

Resource parameters vary from resource to resource; refer to the resource documentation for details.

Here, owner: 'Tony Clifton' is a resource parameter.

describe car(owner: 'Tony Clifton') do
  it { should be_classy }
end

resource-specific matcher

A matcher that operates directly on the resource, as opposed to operating on a property as a [universal matcher](#universal matcher) does.

Resource-specific matchers often provide highly customized behavior. Check the resource documentation to discover which resource-specific matchers are available for your resource.

For example, the hypothetical car resource defines a classy? method, which is exposed as the be_classy matcher in Chef InSpec tests.

describe car(owner: 'Tony Clifton') do
  it { should be_classy }
end

singular resource

A resource intended to uniquely identify a single object on the target. Singular resources specialize in providing richer auditing capabilities via resource-specific matchers. Compare to plural resources.

target

The target is the OS or API on which Chef InSpec is performing audits. In Chef InSpec 1.x, this was always an operating system target (a bare metal machine, VM, or container). In Chef InSpec 2.x and later, this can be an OS target, or an API target, including cloud providers such as AWS. Chef InSpec is agentless, meaning that the Chef InSpec code and profiles remain on your workstation, and the target is remotely interrogated without installing anything.

test

A test is an individual assertion about the state of the resource or one of its properties. All tests begin with the keyword it or its. Tests are grouped within a describe block.

universal matcher

A universal matcher is a matcher that can be used on the properties of any type of resource. For example, you can use the cmp matcher to check the value of properties without having to worry about Ruby type-casting. Universal matchers are almost always used with the its keyword.

Universal matchers are documented on the Universal Matchers page.

Here, we access the 'color' property, then use the cmp universal matcher to compare the property to the 'black' expected result.

describe car(owner: 'Bruce Wayne') do
  its('color') { should cmp 'black' }
end