Writing CFEngine policy
To define new Desired States in CFEngine, you need to write policy files. These are plain text-files, traditionally with a.cf extension.
/var/cfengine/inputs and promises.cf
In CFEngine,cf-agent executes all policies.cf-agent runs every 5 minutesby default, and it executes policies found locally in the/var/cfengine/inputsdirectory. The default policy entry is a file calledpromises.cf. In this fileyou normally reference bundles and other policy files.
Bundles, promise types, and classes oh my!
These concepts are core to CFEngine so they are covered in brief here. For moredetailed information see the Language concepts section of the Reference manual.
Bundles
Bundles are re-usable and blocks of CFEngine policy. The following defines abundle calledmy_test, and it is a bundle for the agent.
bundleagentmy_test{# ...}A bundle contains one or more promise types.
Promise types
Think of a promise type as a way to abstract yourself away from details. Forinstance, there is a promise type called users. This promise type allows you tomanage local users on your system. Instead of using low-level commands to manageusers, with the promise type, you only have one simple syntax that works acrossall operating systems.
The most frequently used promise types arevars,classes,files,packages,users,services,commands andreports. Whenever you want todo some file configuration for example, you would use the files promise type.The following policy ensures the existence of the/tmp/hello-world file:
files:"/tmp/hello-world"create=>"true";When defining desired states it is important to be clear about when and whereyou want this policy to apply. For that, CFEngine has the concept of classes.
Classes
Aclass is an identifier which is used by the agent to decide when and where apart of a policy shall run. A class can either be user-defined, a so calledsoft-class, or it can be a hard class which is automatically discovered anddefined by cf-agent during each run. Popular classes includeany which meansany or all hosts,policy_server which means the host is a policy server. Thereare more than 50 hard classes, and combined with regular expressions this givesyou very granular control.
To see a list of available classes on your host, just type the following command:
cf-promises --show-classesRunning policy
Now let's put the bundle, promise type and class components together in afinal policy. As for classes we will use linux to define that the file/tmp/hello-world must exists on all hosts of typelinux:
bundleagentmy_test{files:linux::"/tmp/hello-world"create=>"true";}bundleagent__main__{methods:"my_test";}Let's save this policy in/tmp/my-policy.cf.
You can now run this policy either in Distributed (client-server) System or in aStand Alone system. The next two sections will cover each of the options.
Option#1: Running the policy on a stand alone system
Since CFEngine is fully distributed we can run policies locally. This can comein handy as the result of a run is instant, especially during the design phasewhere you would like to test out various policies.
To run the file locally, you can log into any of your hosts that has CFEngineinstalled and follow these steps. For this tutorial, use your Policy Server forthis as it is the same cf-agent that runs on the hosts as on the Policy Server.
Tip: Whenever you make or modify a policy, you can use thecf-promisescommand to run a syntax check:
cf-promises -f /tmp/my-policy.cfUnless you get any output, the syntax is correct. Now, to run this policy, simply type:
cf-agent -Kf /tmp/my-policy.cfAs you can see, the response is immediate! Running CFEngine locally like this isideal for testing out new policies. To check that the file has been successfullycreated type:
ls /tmp/hello-world -lIf you want to see what the agent is doing during its run, you can run the agentin verbose mode. Try:
cf-agent -Kf /tmp/my-policy.cf --verboseIn a Stand Alone system, to make and run a policy remember to:
Option#2: Running the Policy on a Distributed System
CFEngine is designed for large-scale systems. It is fully distributed whichmeans that all the logic and decision making takes place on the end-points, orhosts as we call them in CFEngine. The hosts fetch their policies from onecentral distribution point. To continue with this option you need to haveCFEngine running on at least one host and one policy server.
The CFEngine Server typically acts as a policy distribution point. On each host,the cf-agent process runs regularly. This process will by default, every 5minutes, try to connect to cf-serverd on the policy server to check for policyupdates.
By defaultcf-serverd will serve policy from the/var/cfengine/masterfilesdirectory. When the content changes, cf-agent will download the updated files to/var/cfengine/inputs before executing them locally.
This means that by default you should store all your policies in the/var/cfengine/masterfiles directory on your policy server. So, now create/var/cfengine/masterfiles/my-policy.cf with the content of the test policypreviously authored.
NOTE: We recommend that you use a version control system to store the auditlog of your policy.
Now we need to tell CFEngine that there is a new policy in town:
- Create
/var/cfengine/masterfiles/def.jsonwith the following content:
{"inputs":["my-policy.cf"]}On the policy server you can run the following command to make sure the syntaxis correct.
cf-promises -cf /var/cfengine/masterfiles/promises.cfAfter some period of time (CFEngine runs by default every 5 minutes), log in toany of the bootstrapped clients and you will find the/tmp/-hello-world filethere.
Whenever a host connects to the Policy Server, the host will ensure that it hasthemy-policy.cf file from the masterfiles directory exists in the localinputs directory.def.json will also be downloaded with the newinstruction that there is a new policy. Within 5 minutes, whether you have 5Linux hosts or 50,000 Linux hosts, they will all have the/tmp/hello-world fileon their system. Yeah!
If you delete the file, it will be restored by CFEngine at its next run. We callthis a promise repaired. If the file exists during a run, the result would bepromise kept.
Congratulations! You now have the basic knowledge needed to write and runCFEngine policies. Let's continue with an example on how to manage users. Clickhere to continue.
- Overview
- Getting started
- Reference
- Components
- Functions
- accessedbefore
- accumulated
- ago
- and
- basename
- bundlesmatching
- bundlestate
- callstack_callers
- callstack_promisers
- canonify
- canonifyuniquely
- cf_version_after
- cf_version_at
- cf_version_before
- cf_version_between
- cf_version_maximum
- cf_version_minimum
- changedbefore
- classesmatching
- classfiltercsv
- classify
- classmatch
- concat
- countclassesmatching
- countlinesmatching
- data_expand
- data_readstringarray
- data_readstringarrayidx
- data_regextract
- data_sysctlvalues
- datastate
- difference
- dirname
- diskfree
- escape
- eval
- every
- execresult
- execresult_as_data
- expandrange
- file_hash
- fileexists
- filesexist
- filesize
- filestat
- filter
- findfiles
- findfiles_up
- findprocesses
- format
- getclassmetatags
- getenv
- getfields
- getgid
- getindices
- getuid
- getuserinfo
- getusers
- getvalues
- getvariablemetatags
- grep
- groupexists
- hash
- hash_to_int
- hashmatch
- host2ip
- hostinnetgroup
- hostrange
- hostsseen
- hostswithclass
- hubknowledge
- ifelse
- int
- intersection
- ip2host
- iprange
- irange
- isdir
- isexecutable
- isgreaterthan
- isipinsubnet
- islessthan
- islink
- isnewerthan
- isplain
- isreadable
- isvariable
- join
- lastnode
- laterthan
- ldaparray
- ldaplist
- ldapvalue
- length
- lsdir
- makerule
- maparray
- mapdata
- maplist
- max
- mean
- mergedata
- min
- network_connections
- none
- not
- now
- nth
- on
- or
- packagesmatching
- packageupdatesmatching
- parseintarray
- parsejson
- parserealarray
- parsestringarray
- parsestringarrayidx
- parseyaml
- peerleader
- peerleaders
- peers
- processexists
- product
- randomint
- read_module_protocol
- readcsv
- readdata
- readenvfile
- readfile
- readintarray
- readintlist
- readjson
- readrealarray
- readreallist
- readstringarray
- readstringarrayidx
- readstringlist
- readtcp
- readyaml
- regarray
- regcmp
- regex_replace
- regextract
- registryvalue
- regldap
- regline
- reglist
- remoteclassesmatching
- remotescalar
- returnszero
- reverse
- rrange
- selectservers
- shuffle
- some
- sort
- splayclass
- splitstring
- storejson
- strcmp
- strftime
- string
- string_downcase
- string_head
- string_length
- string_mustache
- string_replace
- string_reverse
- string_split
- string_tail
- string_trim
- string_upcase
- sublist
- sum
- sysctlvalue
- translatepath
- type
- unique
- url_get
- usemodule
- userexists
- validdata
- validjson
- variablesmatching
- variablesmatching_as_data
- variance
- version_compare
- Language concepts
- Masterfiles Policy Framework
- promises.cf
- .no-distrib/
- update.cf
- standalone_self_upgrade.cf
- cfe_internal/
- cfe_internal/CFE_cfengine.cf
- cfe_internal/core/
- cfe_internal/core/watchdog
- cfe_internal/core/watchdog/watchdog.cf
- cfe_internal/enterprise/
- cfe_internal/enterprise/federation/
- cfe_internal/enterprise/federation/federation.cf
- cfe_internal/recommendations.cf
- cfe_internal/update/
- cfe_internal/update/cfe_internal_dc_workflow.cf
- cfe_internal/update/cfe_internal_update_from_repository.cf
- cfe_internal/update/lib.cf
- cfe_internal/update/systemd_units.cf
- cfe_internal/update/update_bins.cf
- cfe_internal/update/update_policy.cf
- cfe_internal/update/update_processes.cf
- controls/
- controls/cf_agent.cf
- controls/cf_execd.cf
- controls/cf_hub.cf
- controls/cf_monitord.cf
- controls/cf_runagent.cf
- controls/cf_serverd.cf
- controls/def.cf
- controls/def_inputs.cf
- controls/reports.cf
- controls/update_def.cf
- controls/update_def_inputs.cf
- inventory/
- inventory/any.cf
- inventory/debian.cf
- inventory/freebsd.cf
- inventory/generic.cf
- inventory/linux.cf
- inventory/lsb.cf
- inventory/macos.cf
- inventory/os.cf
- inventory/redhat.cf
- inventory/suse.cf
- inventory/windows.cf
- lib/
- lib/autorun.cf
- lib/bundles.cf
- lib/cfe_internal.cf
- lib/cfe_internal_hub.cf
- lib/cfengine_enterprise_hub_ha.cf
- lib/commands.cf
- lib/common.cf
- lib/databases.cf
- lib/edit_xml.cf
- lib/event.cf
- lib/examples.cf
- lib/feature.cf
- lib/files.cf
- lib/guest_environments.cf
- lib/monitor.cf
- lib/packages.cf
- lib/paths.cf
- lib/processes.cf
- lib/reports.cf
- lib/services.cf
- lib/stdlib.cf
- lib/storage.cf
- lib/testing.cf
- lib/users.cf
- lib/vcs.cf
- modules/
- modules/mustache/
- modules/packages/
- modules/packages/vendored/
- modules/promises/
- modules/promises/cfengine.py
- modules/promises/cfengine.sh
- services/
- services/autorun/
- services/main.cf
- Macros
- Promise types
- Special variables
- All promise and body types
- Release notes
- Web UI
- Settings
- Health
- Hosts
- Alerts and notifications
- Custom actions for alerts
- Enterprise reporting
- Federated reporting
- Measurements app
- Hub administration
- Decommissioning hosts
- Extending Mission Portal
- Extending query builder in Mission Portal
- Adjusting schedules
- Backup and restore
- Configure a custom LDAP port
- Custom LDAPs certificate
- Custom SSL certificate
- Enable plain http
- Lookup license info
- Policy deployment
- Public key distribution
- Re-installing Enterprise hub
- Regenerate self signed SSL certificate
- Reset administrative credentials
- Debugging Mission Portal
- License
- Examples and tutorials
- Example snippets
- General examples
- Administration examples
- Measuring examples
- Software administration examples
- Commands, scripts, and execution examples
- File and directory examples
- File template examples
- Interacting with directory services
- Database examples
- Network examples
- System security examples
- System information examples
- System administration examples
- System file examples
- Windows registry examples
- File permissions
- User management examples
- Common promise patterns
- Aborting execution
- Change detection
- Check filesystem space
- Copy single files
- Create files and directories
- Customize message of the day
- Distribute ssh keys
- Ensure a process is not running
- Ensure a service is enabled and running
- Find the MAC address
- Install packages
- Mount NFS filesystem
- Restart a process
- Set up name resolution with DNS
- Set up sudo
- Set up time management through NTP
- Updating from a central policy server
- Tutorials
- JSON and YAML support in CFEngine
- Installing CFEngine Enterprise agent
- Managing local users
- Managing network time protocol
- Managing processes and services
- Package management
- Writing CFEngine policy
- Distributing files from a central location
- File editing
- Reporting and remediation of security vulnerabilities
- Masterfiles Policy Framework upgrade
- Tags for variables, classes, and bundles
- Custom inventory
- Dashboard alerts
- Integrating alerts with PagerDuty
- Integrating alerts with ticketing systems
- Integrating with Sumo Logic
- Rendering files with Mustache templates
- Reporting
- File comparison
- High availability
- Writing and serving policy
- Example snippets
- Resources
- FAQ
- Why knowledge management?
- Requesting a CFEngine Enterprise License
- Uninstalling / reinstalling
- Agent output email
- Debugging slow queries
- Enterprise Report Filtering
- Enterprise report collection
- Enterprise reporting database
- How can I tell what classes and variables are defined?
- How do I find the public key for a given host
- How do I fix trust after an IP change?
- How do I fix undefined body errors?
- How do I integrate custom policy?
- How do I pass a data type variable?
- Manual execution
- Mustache templating
- Unable to log into Mission Portal
- Users
- What is promise locking?
- Why are remote agents not updating?
- Why are some files inside masterfiles not being updated/distributed?
- Why does CFEngine install into /var/cfengine instead of following the FHS?
- Bootstrapping
- Tuning PostgreSQL
- What did CFEngine do?
- External resources
- Additional topics
- Best practices
- FAQ
- API
- Enterprise API examples
- Enterprise API reference
- Actions API
- Build API
- CMDB API
- Changes REST API
- Federated reporting configuration API
- File changes API
- Health diagnostic API
- Host REST API
- Import & export API
- Import & export compliance report API
- Inventory API
- LDAP authentication API
- Personal groups API
- Query REST API
- SQL schema
- SSH keys API
- Shared groups API
- Status and settings REST API
- Two-factor authentication API
- Users and access-control REST API
- VCS settings API
- Web RBAC API