Create and manage config policies
The config policies feature is available on the Scale Plan and from CircleCI server v4.2. |
Follow the how-to guides on this page to manage, create, and use config policies.
Using server? When using the |
Enable or disable policy evaluation for an organization
Control whether policy evaluation is applied to pipeline configurations within your organization using the --enabled
flag.
-
To enable policy evaluation run the following command. This sets
--enabled
totrue
, which means project configurations will be evaluated against your organization’s policies when pipelines are triggered.:circleci policy settings --enabled=true --owner-id <your-organization-ID>
Example output:
{ "enabled": true }
-
To disable policy evaluation run the following command. This sets
--enabled
tofalse
, which means project configurations will not be evaluated against your organization’s policies when pipelines are triggered.:circleci policy settings --enabled=false --owner-id <your-organization-ID>
Example output:
{ "enabled": false }
To find your organization/user ID, select Organization Settings in the CircleCI web app side bar.
|
Manage policies with your VCS
CircleCI policies are managed by pushing directories of policies to CircleCI via the CLI. There are various ways to manage your policies but here is a list of recommended best practices:
-
Store your policies in a repository in your VCS, within your organization. This is how policies are managed internally at CircleCI. Pushing a policy bundle is done by triggering a CircleCI pipeline.
-
Create a bot account for pushing policies, and use its associated CircleCI personal API token for authentication. For maximum security the token should be stored as an environment variable within a context, and that context should be restricted to groups that are responsible for managing policies. For more information, see the Using Contexts page.
The rest on the steps in this section show how to set up a CI/CD pipeline to manage your policies.
Prerequisites
For the config policies pipeline recommended in this guide you will need to securely manage some environment variables:
-
CIRCLECI_CLI_TOKEN
with the value of a personal API token to authenticate the CLI -
ORG_ID
with the value of the organization ID
You can do this using a context. For more information about setting up and using contexts to securely manage environment variables see the Using contexts page. You might already have a context set up for this or you might want to create a new one. For this example the context name my-context
is used.
-
In the CircleCI web app, select Organization settings > Contexts
-
Click Create Context and enter a name for your context, for example
my-context
-
Click your new context name in the list to access options
-
Click Add Environment Variable and enter
CIRCLECI_CLI_TOKEN
for the environment variable name, and your personal API token string for the value (For more information about this see the Installing the CircleCI local CLI page). Then click Add Environment Variable again to complete. -
Click Add Environment Variable and enter
ORG_ID
for the environment variable name, and your organization ID for the value.To find your organization/user ID, select Organization Settings in the CircleCI web app side bar.
Set up a config policies CI/CD pipeline
-
Set up a repository in your VCS to manage policies. In this example the repository is called
config-policies
. -
Make a local clone of your repository using your preferred method.
-
Create a directory in your new repository for your Rego policy files, for example:
mkdir ./config-policies
-
Create a
.circleci/config.yml
file for your new policies repository, and copy and paste the config example below. This configuration pushes policies to CircleCI on commits to themain
branch, and shows a diff of the policy bundle on commits to all other branches:version: 2.1 orbs: circleci-cli: circleci/circleci-cli@0.1.9 # Use orb to make the `circleci-cli/default` executor available for running jobs workflows: main-workflow: jobs: - diff-policy-bundle: context: my-context filters: branches: ignore: main # on all branches other than main - push-policy-bundle: context: my-context filters: branches: only: main # only on the main branch jobs: diff-policy-bundle: executor: circleci-cli/default resource_class: small steps: - checkout - run: name: Diff policy bundle command: circleci policy diff ./config-policies --owner-id $ORG_ID # show a diff of the policy bundle push-policy-bundle: executor: circleci-cli/default resource_class: small steps: - checkout - run: name: Push policy bundle command: circleci policy push ./config-policies --no-prompt --owner-id $ORG_ID # push the policy bundle to CircleCI
Your file structure should now look something like:
. ├── README.md ├── .circleci └── config.yml └── config-policies
The context for each job is shown as
my-context
. This context name is arbitrary, but it must be active and declare the following environment variables:-
CIRCLECI_CLI_TOKEN
with the value of a personal API token to authenticate the CLI -
ORG_ID
with the value of the organization ID
For setup steps see the Prerequisites on this page.
-
Create a policy
Once you have decided how to manage your policies, the next step is to create a policy. Follow the steps in this section to create a policy that checks the version
of CircleCI config files to ensure version
is greater than or equal to 2.1
.
1. Write your policy
Ensure you have authenticated your version of the CLI with a token, and updated the CLI, before attempting to use the CLI with config policies. See the Installing the Local CLI page for more information. |
-
Enable config policies for your organization, if you have not already done so.
-
If you have followed the steps above to set up CI/CD for your config policies, you will already have a directly for storing your policies. If not, create an empty directory to store your policies. For example:
mkdir ./config-policies
-
Inside your new directory create a Rego file for your new policy. Call it,
version.rego
. -
Add the following content to
version.rego
:# All policies start with the org package definition package org policy_name["example"] # signal to circleci that check_version is enabled and must be included when making a decision # Also, signal to circleci that check_version is a hard_failure condition and that builds should be # stopped if this rule is not satisfied. enable_hard["check_version"] # define check version check_version = reason { not input.version # check the case where version is not in the input reason := "version must be defined" } { not is_number(input.version) # check that version is number reason := "version must be a number" } { not input.version >= 2.1 # check that version is at least 2.1 reason := sprintf("version must be at least 2.1 but got %v", [input.version]) }
2. Push up your policy bundle
You can now push your new policy to your organization for it to take effect. You have two options:
-
Push the policy manually using the CLI from your local environment
-
Push your changes to your config policy repository if you are managing policies via your VCS as shown above.
Now, when a pipeline is triggered within your organization, the project’s .circleci/config.yml
will be validated against this policy.
3. Update your policy
To illustrate making a change to an existing policy, suppose you made an error when creating the policy above. You realize that some project configurations in your organization are using CircleCI config version 2.0
, and you want your policy to reflect this.
-
Change the last check of your rule definition in your
version.rego
file to:{ not input.version >= 2.0 # check that version is at least 2.0 reason := sprintf("version must be at least 2.0 but got %v", [input.version]) }
-
Push the policy directory containing the updated policy:
Next steps
If you would like to write tests for your policy, check out the Test config policies guide.