2016-09-21 16:58:25 +00:00
---
title: Resource DSL
---
# Resource DSL
2019-04-26 18:24:29 +00:00
Chef InSpec provides a mechanism for defining custom resources. These become
2016-09-21 16:58:25 +00:00
available with their respective names and provide easy functionality to
profiles.
## Resource location
Resources may be added to profiles in the libraries folder:
```bash
$ tree examples/profile
examples/profile
...
├── libraries
2019-10-09 07:08:28 +00:00
│ └── example_config.rb
2016-09-21 16:58:25 +00:00
```
## Resource structure
The smallest possible resource takes this form:
```ruby
class Tiny < Inspec.resource ( 1 )
name 'tiny'
end
```
Resources are written as a regular Ruby class which inherits from
Inspec.resource. The number (1) specifies the version this resource
2019-04-26 18:24:29 +00:00
plugin targets. As Chef InSpec evolves, this interface may change and may
2016-09-21 16:58:25 +00:00
require a higher version.
The following attributes can be configured:
2018-03-22 12:47:31 +00:00
- name - Identifier of the resource (required)
- desc - Description of the resource (optional)
- example - Example usage of the resource (optional)
2019-04-26 18:24:29 +00:00
- supports - (Chef InSpec 2.0+) Platform restrictions of the resource (optional)
2016-09-21 16:58:25 +00:00
The following methods are available to the resource:
2018-03-22 12:47:31 +00:00
- inspec - Contains a registry of all other resources to interact with the operating system or target in general.
- skip\_resource - A resource may call this method to indicate that requirements aren't met. All tests that use this resource will be marked as skipped.
2016-09-21 16:58:25 +00:00
The following example shows a full resource using attributes and methods
to provide simple access to a configuration file:
```ruby
2019-10-09 07:08:28 +00:00
class ExampleConfig < Inspec.resource ( 1 )
name 'example_config'
2016-09-21 16:58:25 +00:00
2018-03-22 12:47:31 +00:00
# Restrict to only run on the below platforms (if none were given, all OS's supported)
supports platform_family: 'fedora'
supports platform: 'centos', release: '6.9'
# Supports `*` for wildcard matcher in the release
supports platform: 'centos', release: '7.*'
2016-09-21 16:58:25 +00:00
desc '
Resource description ...
'
example '
2019-10-09 07:08:28 +00:00
describe example_config do
2016-09-21 16:58:25 +00:00
its("signal") { should eq "on" }
end
'
# Load the configuration file on initialization
def initialize(path = nil)
2019-10-09 07:08:28 +00:00
@path = path || '/etc/example.conf'
2016-09-21 16:58:25 +00:00
@params = SimpleConfig.new( read_content )
end
# Expose all parameters of the configuration file.
def method_missing(name)
@params [name]
end
private
def read_content
f = inspec.file(@path)
# Test if the path exist and that it's a file
if f.file?
# Retrieve the file's contents
f.content
else
2019-10-09 07:08:28 +00:00
# If the file doesn't exist, skip all tests that use example_config
2018-04-05 12:50:49 +00:00
raise Inspec::Exceptions::ResourceSkipped, "Can't read config at #{@path}"
2016-09-21 16:58:25 +00:00
end
end
end
```
2019-10-09 07:08:28 +00:00
For a full example, see our [example resource ](https://github.com/chef/inspec/blob/master/examples/profile/libraries/example_config.rb ).
2019-10-17 00:09:04 +00:00
## Lazy Loading
Prior to InSpec v4.16, resources were pre-loaded for every invocation
of `inspec` . This was a heavy and unnecessary burden on the system and
exacerbated startup times (especially on Windows).
As of InSpec v4.16, resources are lazily loaded into the `inspec`
process upon use. This greatly speeds up the initial startup costs of
2019-10-21 19:34:59 +00:00
the `inspec` process and only loads what you need to use. For example, `inspec
2019-10-21 19:35:09 +00:00
--version` no longer runs for 10 seconds!.
2019-10-17 00:09:04 +00:00
### Overriding Core Resources
Lazy loading does change the way the resource registry is handled in
ways that might break some assumptions. Specifically,
`inspec.<resource>` isn't pre-populated with the core resources that
InSpec ships with. If you make a local/custom resource of the same
name, referring to the core resource via `inspec.<resource>` will not
resolve to the core resource.
As such, overriding core resources is not recommended best practice.
If you really do need to do this, it is easiest to make a local
resource with a new name and refer to the core resource directly.
Otherwise, you need to ensure that the core resource you want is
registered (via `require "inspec/resource/<name>"` ) _before_ your
profile is run to ensure it is eagerly loaded and in the global
resource registry.