The previous two installments in this blog series covered an array of Progress Chef InSpec commands used to manage large profiles, integrate with third-party systems and perform other useful functionalities. In this third part of the series, we are looking at another feature of Chef InSpec: writing controls for cloud resources.
Progress Chef Cloud Security scans and identifies configuration issues across on-premises and cloud-native environments in your multi-cloud accounts. With the assistance of CIS and DISA STIG-certified audit and remediation content, Chef Cloud Security helps your IT resources better maintain compliance across your systems. You can tune baselines to adapt to the organization’s internal requirements more easily while gaining additional visibility and control over your organization’s security and compliance posture.
As discussed in the previous blog posts, Chef InSpec is the engine behind Chef Compliance and Chef Cloud Security, and it uses an open-source framework for defining security and compliance rules as executable code. This framework is designed to assist with the software delivery life cycle.
As more diverse technologies are deployed across data centers and hybrid or multi-cloud estates, validating and maintaining organization-wide compliance is becoming increasingly difficult. Organizations must cater to numerous regulatory requirements to comply and avoid legal hassles. Chef Compliance enables you to help reinforce your infrastructure against defined regulatory controls.
But did you know that you can write custom controls for cloud resources with Chef InSpec?
Let’s dive in.
Chef InSpec uses profiles to audit infrastructure.
A Chef InSpec profile organizes multiple controls into a reusable artifact. A control defines a regulatory recommendation or requirement for the state of a system. Each profile can have many controls and each control audits different aspects of a system. You can describe your profiles with metadata, version them, pin them to specific versions of Chef InSpec and define specific platforms capable of testing a profile and its dependencies.
Profiles can also contain resources. Chef InSpec resources allow you to test specific parts of your infrastructure. Chef InSpec has 1106 ready-to-use resources from Apache2 to the ZFS pool. This includes resources for testing AWS, Azure and GCP cloud infrastructure.
You can create your own custom resources if Chef InSpec doesn’t have a resource that meets your needs. A resource pack is a Chef InSpec profile containing custom resources and no other controls or tests.
Before we delve into writing controls for resource packs, let us understand some basics of Chef InSpec, such as transport interface, resource packs and inputs.
Chef InSpec TRAnsport INterface or Train provides a unified back-end interface to InSpec, enabling common interaction with different target types (local, remote, or API), as shown in the image below.
Train works with built-in or custom libraries to help identify the system platform being evaluated during a test run. Train includes built-in platform/transport support and can be extended with plugins to include additional platforms or transports. Read this additional information on plugins, including Train plugins.
Chef InSpec includes many built-in resources. Additionally, custom resources are provided as a resource pack. A resource pack is a Chef InSpec profile that does not provide any content for control tests; instead, it defines custom resources. Resource packs can be easily included in a Chef InSpec profile by using the “depends” syntax in the “inspec.yml” file of a profile (as shown in the following image).
Chef InSpec inputs allow for creating pluggable or custom configurations used at runtime execution of the InSpec profile. Common use cases for inputs include:
The following sample snippet shows how to define the input in a compliance profile for GCP. It can be set to “required”; the default value is “false” if not otherwise specified. The input values can also be specified at the profile level to apply to any included controls. In this example, we have defined the name, description, value and priority of each input.
# Project inspec.yml file
name: my-gcp-profile
title: GCP inspec Profile
license: Apache-2.0
summary: An inspec Compliance Profile For GCP
version: 0.1.0
inspec_version: '>= 2.3.5’
# Inputs are defined as an array of objects
inputs:
- name: gcp_project_id
required: true
description: 'The GCP project identifier.'
- name: gcp_region
description: 'Optional GCP region to target.'
value: us-central
priority: 10
depends:
- name: inspec-gcp
url: https://github.com/inspec/inspec-gcp/archive/master.tar.gz
supports:
- platform: gcp
Here is another snippet showing the usage of Chef InSpec input.
control 'bike_color_test' do
impact 0.1
title 'Our bike should match the specified color'
# Set the Input value
input('bike_color', value: 'blue’)
describe('blue') do
it { should cmp input('bike_color') }
end
describe input('bike_color') do
it { should cmp 'blue’ }
end
end
Input values can be specified at multiple locations within a profile. The precedence of the input is determined by the place where it is set. If there are conflicting values, the value with the highest priority is used. The following table lists the default priority for input methods in order from lowest priority (20) to highest priority (50).
Additional information on input is available under the Chef InSpec section of this document.
Chef InSpec includes several cloud providers with platform support and native InSpec resources.
Platform | Doc Links |
---|---|
Alibaba Cloud | GitHub: inspec/inspec-alicloud |
Amazon Web Services | Chef Docs: AWS Resources |
Azure | Chef Docs: Azure Resources |
Digital Ocean | GitHub: inspec/inspec-digitalocean |
Google Cloud Platform | Chef Docs: GCP Resources |
Additional custom or community cloud resource packs can be used by specifying a dependency in the profile’s inspec.yml file, indicating the source location for the custom provider.
Now that we have covered the basics, we can look at creating profiles for AWS and writing controls for these. For each, we will:
The first step is to create a profile that makes use of cloud resources. The process is similar to creating an OS InSpec profile. Command line support with pre-configured information and example resources are available for InSpec profiles for GCP, AWS and Azure.
The code below creates a profile to be used as a starting point for AWS scanning.
● Name: The name of the InSpec profile that we will create (my-aws-profile).
● Platform: The name of the platform we will use for this profile. Options are aws, azure, gcp and os (default).
# switch to a working directory to use for example creation mkdir ~/inspec_cloud_resource_examples cd ~/inspec_cloud_resource_examples $ inspec init profile my-aws-profile --platform=aws
Output:
The newly created Chef InSpec profile has the baseline configuration which is required to start scanning against an AWS target defined in the “inspec.yml” file. The “depends” object identifies a reliance on the “inspec-aws” profile from GitHub which contains the resource pack contents.
# my-aws-profile/inspec.yml name: my-aws-profile title: AWS inspec Profile maintainer: The Authors copyright: The Authors copyright_email: you@example.com license: Apache-2.0 summary: An inspec Compliance Profile For AWS version: 0.1.0 inspec_version: '~> 4’ inputs: - name: aws_vpc_id required: false # Below is deliberately left as a default empty string to allow the profile to run when this is not provided. # Please see the README for more details. value: '' description: 'Optional Custom AWS VPC Id' type: string depends: - name: inspec-aws url: https://github.com/inspec/inspec-aws/archive/master.tar.gz supports: - platform: aws
Next, review the profile.
An example control file is created when generating the profile, it has a sample resource to help you get started. The controls created will perform checks to see if VPC objects exist and then checks to verify that the default security groups do not allow port 22 inbound (SSH).
Many of the Chef InSpec resources available in cloud resource packs have both a singular and plural version of the resources. In addition to the pre-generated controls, we can create additional controls.
In this example, let’s create a control to validate “multi-factor authentication is enabled for all user accounts.” This can be accomplished by using the plural aws_iam_users resource which allows testing for criteria against all discovered IAM user objects. This new control will be appended to our controls/example.rb file.
Additional information for this resource.
Testing profiles is an important step in the development process, as it helps provide insight to what controls are currently working. With Chef Workstation installed, testing can be performed locally (if credential access is available) to execute the new profile with InSpec exec:
This profile will be scanned against an AWS backend target so the option “-t aws://” is added to the Chef InSpec command. Adding the target option specifies what back-end type (using Train) should be used (default is the local OS). You will also need to provide the AWS credential information to Chef InSpec for scanning.
In the following example, AWS_REGION and AWS_PROFILE will be exported to the environment of the running shell. You can reference the AWS resource pack documentation for more details.
Summary
This blog series showcases the multitude of options available to you with Chef InSpec. In this post, we highlighted how Chef InSpec can be used to create cloud resource packs—specifically for AWS. The ability to write custom controls, create your own controls and use resource packs to obtain pre-defined controls, are several advantages of using Chef InSpec.
Dig deeper into the features and functionality of Chef InSpec by exploring the resources on Chef Docs and Learn Chef.