Managing Custom Rules - CLI¶
Note
For UI instructions, see Managing Custom Rules - UI.
For API instructions, see Managing Custom Rules - API.
Just looking for info on writing custom rules? See Writing Custom Rules.
Fugue’s CLI allows you to test, create, update, and delete custom rules.
Creating Custom Rules - CLI¶
Creating a custom rule via the CLI generally involves three steps:
Optional: Get the input for a custom rule test (CLI Reference)
Optional: Test the custom rule (CLI Reference)
Creating a Rule via CLI - Get Input for Test¶
It’s a best practice to test a custom rule with the CLI before adding it to your tenant. To test a custom rule, we recommend that you retrieve test input first, which is scan data to test the rule against. You can use this test input to help you write the rule. Then, you run the test by providing Fugue with the rule and the scan ID. Fugue tests the rule against the resources recorded in that scan.
You don’t have to test a rule; you can skip ahead to adding it, and the CLI will reject it if the syntax is incorrect, but you won’t know if it produces the intended results until after the next scan. We highly recommend you test rules before adding them.
To retrieve the scan data from the CLI, start by finding the scan ID for the data you want to use with the fugue list scans [environment_id] command. You’ll need the environment ID you want to grab a scan from:
fugue list scans e3717b3f-dd1c-4f07-bbc6-eccf804c4771
You can copy the ID from any past scan, or you can manually kick off a new scan with fugue scan [environment_id] and use that ID.
Next, execute the fugue get rule-input –scan [scan_id] command to retrieve the rule test input. We’ll redirect the output of the command to a new file, input.json
:
fugue get rule-input --scan fc9f777e-0acb-4054-b133-2de1da174e04 > input.json
If you open up input.json
, you’ll see the CLI response is a JSON representation of each resource in your environment from that scan. Here’s an abbreviated example of two VPCs:
{
"resources": {
"aws_vpc.dnBjLTAyYjEwMjQ4123456789012": {
"_skeleton": {
"depends_on": null,
...
},
...
"cidr_block": "10.0.0.0/16",
"id": "vpc-02b10248f12345678",
"tags": {
"Name": "my-vpc",
"Application": "Portal"
}
},
"aws_vpc.dnBjLT9999999999": {
"_skeleton": {
"depends_on": null,
...
},
...
"cidr_block": "172.31.0.0/16",
"id": "vpc-92281234",
"tags": {}
}
}
}
Once you have this information, you can determine the expected result of your custom rule test. For example, if you are writing a rule that tests whether all VPCs in an environment have the tag key Application
and the tag value Portal
, the scan data can tell you that one VPC should pass (vpc-02b10248f12345678
) and one should fail (vpc-92281234
).
Using Test Input to Write Rules
You can also use the infrastructure state JSON to determine the resource attributes and syntax for writing custom rules. The way resource configuration is structured in the scan data is the same structure Fugue expects for custom rules.
So, let’s say your scan data includes an Amazon VPC like this one (cut for length):
{
"resources": {
...
"aws_vpc.dnBjLTAyYjEwMjQ4123456789012": {
...
"_type": "AWS.EC2.Vpc",
"cidr_block": "10.0.0.0/16",
"id": "vpc-02b10248f12345678",
"tags": {
"Name": "my-vpc",
"Application": "Portal"
}
}
}
}
The example simple rule below uses the syntax input.tags.Application
to pass VPCs tagged with the key Application
and value Portal
, following the JSON structure of the input above:
allow {
input.tags.Application == "Portal"
}
In the example below, which is an advanced version of the simple rule above, we used the variable vpc
to refer to an individual VPC and used vpc.tags.Application
to refer to the VPC tag key Application
following the JSON structure of the input:
policy[p] {
vpcs = fugue.resources("AWS.EC2.Vpc")
vpc = vpcs[_]
vpc.tags.Application == "Portal"
p = fugue.allow_resource(vpc)
} {
vpcs = fugue.resources("AWS.EC2.Vpc")
vpc = vpcs[_]
not vpc.tags.Application == "Portal"
p = fugue.deny_resource(vpc)
}
Creating a Rule via CLI - Test the Rule¶
You can determine whether a custom rule will work by testing the code against infrastructure state from a particular scan. This will help you determine correctness of syntax and accuracy of results.
Start by using the fugue list scans [environment_id] command to get the scan ID for the data you want to use, if you haven’t already. You can use the ID from any past scan, or you can manually kick off a new scan with the fugue scan [environment_id] command and use that ID.
Next, execute the fugue test rule [rego file] command. You’ll need to specify the resource type of the rule and the scan ID, and pass in the Rego file containing your rule code.
Specifying the resource type
The way you specify the resource type depends on the type of rule (simple or advanced), provider(s), and method of uploading to Fugue.
Use
resource_type = {resource_type}
for simple rules, e.g.,resource_type = "aws_s3_bucket"
Use
resource_type = "MULTIPLE"
for advanced rulesUse
resource_type = "DEFINED_IN_CODE"
if your resource type is defined in the Rego code. Defining your rule in code is optional, except in the following scenarios where you must define it as code:You’re uploading the rule via fugue sync rules, and/or:
The rule is for multiple providers of any type, and/or:
The rule is for the
REPOSITORY
provider
If the resource type is set to DEFINED_IN_CODE
, ensure the Rego code contains a resource_type = {resource_type}
line if it’s a simple rule, or resource_type = "MULTIPLE"
if it’s advanced.
For more information, see Custom Rules Reference, Simple Rules, and Advanced Rules.
Here’s an example command. We decided to include the resource type in the Rego code, so we set the --resource-type
flag to DEFINED_IN_CODE
:
fugue test rule --resource-type "DEFINED_IN_CODE" \
--scan fc9f777e-0acb-4054-b133-2de1da174e04 rule.rego
The example rule.rego
file contains this code:
package rules.app_tag
default allow = false
resource_type = "aws_vpc"
allow {
input.tags.Application == 'Portal'
}
Fugue returns the results of the rule if the syntax is correct, or an error if Fugue cannot parse it. (Note that the CLI cannot report semantic errors, only parsing errors – just like programming in general, confirm that your custom rule has the expected results before you add it to your tenant!)
Example rule results:
========================================
ID | RESULT | TYPE
========================================
vpc-05621851a2b3c4d5e | PASS | aws_vpc
vpc-07f46019987654321 | FAIL | aws_vpc
Example error message:
fregot (rules_engine error):
Expected at least one `allow` or `deny` rule in the module for a single resource type rule.
Creating a Rule via CLI - Add the Rule¶
Getting scan data and testing a rule are not prerequisites for adding a rule via the CLI, but we strongly recommend taking these steps first. The Fugue CLI checks the syntax when you add the rule but cannot report semantic errors, so you won’t know if the rule has the intended results until after the next scan.
There are two methods of creating rules via the CLI:
fugue create rule creates a single rule
fugue sync rules uploads a directory of one or more rules
Creating a single rule¶
Tip
Using a version control system such as Git? We highly recommend using the fugue sync rules [directory] command instead to programmatically sync the rules in a repository to Fugue through CI/CD.
To create a single rule, use the fugue create rule command:
fugue create rule --description "Amazon VPCs must be tagged with Application:Portal" \
--name "VPCs require Application:Portal tags" \
--provider "AWS" --resource-type "DEFINED_IN_CODE" \
--severity "High" \
--text "package rules.app_tag
default allow = false
resource_type = \"aws_vpc\"
allow {
input.tags.Application == 'Portal'
}"
Tip
Remember to escape any double quotes with a \
character!
Fugue returns the details about the newly added rule if the syntax is correct, or an error if Fugue cannot parse it or encounters another error. (Note that the CLI cannot report semantic errors, only parsing errors – just like programming in general, confirm that your custom rule has the expected results before you add it to your organization!)
Example output for a rule created successfully – note that STATUS
is ENABLED
:
============================================================================
ATTRIBUTE | VALUE
============================================================================
RULE_ID | eefbd194-e73f-4930-a22d-7c64fd912bbe
NAME | VPCs require Application:Portal tags
DESCRIPTION | Amazon VPCs must be tagged with Application:Portal
PROVIDER | AWS
RESOURCE_TYPE | DEFINED_IN_CODE
SEVERITY | High
STATUS | ENABLED
FAMILIES | -
CREATED_AT | 2021-11-14T22:46:53-05:00
CREATED_BY | api_client:003897de-19e9-405d-9faa-0949e145e6ba
CREATED_BY_DISPLAY_NAME |
UPDATED_AT | -
UPDATED_BY |
UPDATED_BY_DISPLAY_NAME |
Example error message – note that STATUS
is INVALID
:
============================================================================
ATTRIBUTE | VALUE
============================================================================
RULE_ID | eefbd194-e73f-4930-a22d-7c64fd912bbe
NAME | VPCs require Application:Portal tags
DESCRIPTION | Amazon VPCs must be tagged with Application:Portal
PROVIDER | AWS
RESOURCE_TYPE | DEFINED_IN_CODE
SEVERITY | High
STATUS | INVALID
FAMILIES | -
CREATED_AT | 2021-11-14T23:04:40-05:00
CREATED_BY | api_client:003897de-19e9-405d-9faa-0949e145e6ba
CREATED_BY_DISPLAY_NAME |
UPDATED_AT | -
UPDATED_BY |
UPDATED_BY_DISPLAY_NAME |
Uploading a directory of rules¶
Tip
The fugue sync rules [directory] command is ideal if you’re using version control software such as Git. You can programmatically sync the rules in a repository to Fugue via CI/CD.
The fugue sync rules [directory] command allows you to upload a directory of Rego files to Fugue. If a rule name exists, the rule is updated; otherwise, a new rule is created.
Example command:
fugue sync rules my-rules-directory
Note that each Rego file must contain metadata to indicate the rule title, description, and provider(s) at a minimum.
Here’s an example rule with metadata:
package rules.vpc_tag_app
__rego__metadoc__ := {
"title": "VPCs require Application:Portal tags",
"description": "Amazon VPCs must be tagged with Application:Portal",
"custom": {
"providers": ["AWS"],
"severity": "High"
}
}
default allow = false
resource_type = "aws_vpc"
allow {
input.tags.Application == "Portal"
}
Note
HTTP header metadata is deprecated. We recommend using the newer __rego__metadoc__
method detailed in the Custom Rules Reference.
After you execute fugue sync rules [directory]
, you’ll see output like this:
Creating rule VPCs require Application:Portal tags
Note that if a rule name already exists, Fugue will overwrite (update) the rule:
Updating rule VPCs require Application:Portal tags
Modifying and Deleting Custom Rules - CLI¶
Modifying Custom Rules - CLI¶
Getting scan data and testing a rule are not prerequisites for modifying a rule via the CLI, but we strongly recommend taking these steps first. The Fugue CLI checks the syntax when you update the rule but cannot report semantic errors, so you won’t know if the rule has the intended results until after the next scan.
There are two methods of updating rules via the CLI:
fugue update rule updates a single rule
fugue sync rules uploads a directory of one or more rules
Updating a single rule¶
Tip
Using a version control system such as Git? We highly recommend using the fugue sync rules [directory] command instead to programmatically sync your rules to Fugue through CI/CD.
Start by finding the rule ID for the rule you want to update. You can do this by executing the fugue list rules command and then looking for the ID of the desired rule:
fugue list rules
In the output, look for the ID
column:
======================================================================================================================================================================================================================================================================
ID | NAME | PROVIDER | SEVERITY | RESOURCE_TYPE | STATUS | DESCRIPTION | FAMILIES
======================================================================================================================================================================================================================================================================
eefbd194-e73f-4930-a22d-7c64fd912bbe | VPCs require Application:Portal tags | AWS | Medium | aws_vpc | INVALID | Amazon VPCs must be tagged wi... | c4e28bd,Custom
8eedf0bd-339d-4fb8-b6ad-b9dae518825e | All taggable AWS and Azure resources must be tagged | AWS | Medium | DEFINED_IN_CODE | DISABLED | If it's taggable, tag it. | Custom
7b643bde-76c1-4640-9372-70dc4919416c | An AWS account must have a password policy requiring a minimum of 16 characters | AWS | Medium | MULTIPLE | ENABLED | An AWS account must have a pa... | Custom
Once you have the ID of the rule you want to update, execute the fugue update rule [rule_id] command and specify the flag(s) you want to update:
fugue update rule eefbd194-e73f-4930-a22d-7c64fd912bbe --severity "Medium"
You’ll see output like this:
============================================================================
ATTRIBUTE | VALUE
============================================================================
NAME | VPCs require Application:Portal tags
DESCRIPTION | Amazon VPCs must be tagged with Application:Portal
PROVIDER | AWS
SEVERITY | Medium
RESOURCE_TYPE | DEFINED_IN_CODE
STATUS | ENABLED
FAMILIES | Custom
CREATED_AT | 2021-11-15T05:23:57-05:00
CREATED_BY | api_client:003897de-19e9-405d-9faa-0949e145e6ba
CREATED_BY_DISPLAY_NAME |
UPDATED_AT | 2021-11-15T05:29:44-05:00
UPDATED_BY | api_client:003897de-19e9-405d-9faa-0949e145e6ba
UPDATED_BY_DISPLAY_NAME |
Updating a directory of rules¶
Tip
The fugue sync rules [directory] command is ideal if you’re using version control software such as Git. You can programmatically sync your rules to Fugue via CI/CD.
The fugue sync rules [directory] command allows you to upload a directory of Rego files to Fugue. If a rule name exists, the rule is updated; otherwise, a new rule is created.
See Uploading a directory of rules for more information.
Example Rules¶
For examples of simple and advanced custom rules, see our GitHub repo.
Deleting Custom Rules - CLI¶
Start by executing fugue list rules to find the ID for the rule you want to update, if you haven’t already.
Then, execute the fugue delete rule [rule_id] command:
fugue delete rule eefbd194-e73f-4930-a22d-7c64fd912bbe
If the delete call is successful, there is no output.
Note
If you delete or disable a custom rule, the rule is not removed from an environment until after the next scan. The deleted or disabled rule continues to display in the environment’s compliance tabs and the pass/fail results count toward your compliance posture. After the next scan, the rule is removed from the environment and results are not counted toward your compliance posture.
Viewing Compliance Results - CLI¶
All custom rules with valid syntax automatically run against environments with the Custom family enabled on their next scan. After the scheduled scan runs or is kicked off manually with fugue scan [environment_id], you can request the Custom compliance family results from the CLI.
Additionally, the three compliance endpoints allow you to take a deeper dive into why your custom rule is passing or failing.
Compliance by Resource - CLI¶
The CLI does not currently support viewing compliance by resource. To view compliance by resource results in the UI, see Compliance by Resource - UI.
Compliance by Resource Type - CLI¶
To view compliance by resource type using the CLI, use the fugue get compliance-by-resource-types [scan_id] command:
fugue get compliance-by-resource-types 4b66a672-fc9c-4674-9b5c-4df42d23a40c
You’ll see output like this:
======================================================================
RESOURCE_TYPE | COMPLIANT | NONCOMPLIANT | TOTAL
======================================================================
AWS.ACM.Certificate | 1 | 0 | 1
AWS.AutoScaling.LaunchConfiguration | 2 | 0 | 2
AWS.CloudFront.Distribution | 0 | 1 | 1
<cut for length>
Compliance by Control - CLI¶
To view compliance by control using the CLI, use the fugue get compliance-by-rules [scan_id]:
fugue get compliance-by-rules 4b66a672-fc9c-4674-9b5c-4df42d23a40c
You’ll see output like this:
===================================================
FAMILY | RULE | RESULT
===================================================
AWS-Well-Architected_v2020-07-02 | REL10.1 | FAIL
AWS-Well-Architected_v2020-07-02 | REL6.1 | FAIL
AWS-Well-Architected_v2020-07-02 | REL9.1 | PASS
<cut for length>
Waiving Custom Rules - CLI¶
To waive a rule using the CLI, see the fugue create rule-waiver command.
Disabling and Enabling Custom Rules - CLI¶
The CLI does not support enabling and disabling rules; use the UI or API instead. See Enabling and Disabling Rules for more information.