CoursesInSpecIntermediate

Profiles, inputs & metadata

Package and parameterize controls.

Intermediate12 min · lesson 6 of 12

A profile is a packaged, versioned collection of controls with metadata — the unit you share, run, and inherit. It has a standard layout: an inspec.yml (name, version, supported platforms, dependencies, inputs), a controls/ directory, an optional libraries/ for custom resources, and files for test data. inspec init profile scaffolds it. Packaging controls as a profile is what turns a pile of checks into a distributable compliance artifact.

inspec.yml
name: acme-linux-baseline
title: Acme Linux Security Baseline
version: 1.4.0
supports:
- platform-family: debian
inputs:
- name: ssh_port
type: numeric
value: 22
depends:
- name: cis-dil-benchmark
url: https://.../cis-dil-benchmark.tar.gz

Inputs make profiles reusable

Inputs (formerly attributes) parameterize a profile so one profile serves many environments — the SSH port, an allowed-users list, a threshold — supplied at run time via --input or an input file, with defaults in inspec.yml. Controls read them with input(‘ssh_port’). This is the same parameterization idea as Ansible variables or Helm values: keep the control logic general and push environment specifics into inputs, so a baseline profile adapts without editing its controls.

control using input
control 'ssh-port' do
describe port(input('ssh_port')) do
it { should be_listening }
end
end
# inspec exec my-profile --input ssh_port=2222
Version and pin profiles like any dependency
A profile is code that gates compliance, and profiles depend on other profiles (baselines), so version them semantically and pin the versions you depend on in inspec.yml. An unpinned dependency pulls whatever the upstream baseline is today, changing what “compliant” means under you. Commit the lock, review baseline bumps, and treat a profile bump as a deliberate change to your compliance definition.