Guides
PR bot configuration
How the optional .levelfour/config.yml file tunes the PR bot per repository, where it lives, every field with its default, and what it does not control.
Once you install LevelFour on a GitHub organization, the PR bot is on by default for every repository you granted access to. On every pull request, LevelFour reads the Terraform and CloudFormation changes in the diff, computes cost impact, and posts a single check-run comment with the cost breakdown. When LevelFour has concrete patch suggestions, they appear as inline "Suggested change" boxes on the diff itself. The main comment does not list them.
You tune the bot per repo with a .levelfour/config.yml file at the root of the default branch. The file is optional. With no file, the bot uses the defaults documented below.
.levelfour/config.yml. Until then, every per-repo override lives in this file.Where the file lives
Path: .levelfour/config.yml at the repository root, on the default branch.
The bot reads this file at the start of every pull request analysis. Changes take effect on the next PR or push, never on an analysis that has already run.
To check a file before it matters, copy one of the examples below into your repo and open a draft PR. Validation behavior covers what comes back.
Quick examples
Disable the bot on a single repository
enabled: falseThis does not stop LevelFour reading the repo. See what this file does not control.
Drop inline patch suggestions, keep the cost comment
code_suggestions_enabled: falseThe bot still posts the cost summary on each PR, but does not propose inline "Suggested change" boxes on the diff.
Exclude test fixtures and a noisy resource type
excluded_paths:
- tests/fixtures/**
- examples/**
excluded_resource_types:
- aws_iam_role_policy_attachment
- AWS::Logs::*Write each type the way its own language does: aws_* for Terraform, AWS::Service::Resource for CloudFormation.
Price a CloudFormation template with its production parameters
cloudformation:
samconfig_env: prod
parameter_files:
stacks/app.yaml: stacks/params/prod.jsonThe bot prices stacks/app.yaml with the values in stacks/params/prod.json, and reads the prod environment from any samconfig file beside a template. CloudFormation has the order the bot reads them in.
Pin all cost estimates to a specific region
region_override: us-east-1Reach for this when your Terraform omits provider "aws" { region = ... } and the bot would otherwise default to the global price. For CloudFormation it also wins over the region in samconfig.
Schema
| Field | Type | Default | What it does |
|---|---|---|---|
enabled | bool | true | Master switch. When false, the bot skips this repo. No comments, no check runs. |
code_suggestions_enabled | bool | true | When false, the bot still posts the cost comment but does not propose inline patch suggestions. |
max_code_suggestions | int (0 to 25) | 25 | Cap on inline suggestion comments per PR. A suggestion that needs a second setting changed with it, such as gp3 with its IOPS, posts as one comment per line and counts each one. The bot never posts part of such a pair. Lower it if the bot is too chatty on large changes. |
excluded_resource_types | string[] | [] | Resource type globs to skip, in each language's own type names. Example: aws_iam_* matches every Terraform IAM resource, AWS::IAM::* every CloudFormation one. |
excluded_paths | string[] | [] | File path globs to skip, for Terraform files and CloudFormation templates alike. Example: tests/fixtures/**. |
region_override | string or null | null | Pin all cost estimates to one AWS region. |
cloudformation.enabled | bool | true | When false, the bot skips CloudFormation templates and prices Terraform only. |
cloudformation.paths | string[] | [] | Path globs that pick which templates the bot prices. Empty picks every template in the repository. A template outside them is still read when a picked template nests it. |
cloudformation.samconfig_env | string | default | The samconfig environment whose parameter_overrides and region apply. |
cloudformation.parameter_files | map | {} | A parameters file for each template, both as paths from the repository root. |
graviton_for_managed_services_enabled | bool | false | Opt in to Graviton-vs-Intel suggestions for AWS managed services (RDS, ElastiCache, OpenSearch). Off by default while the rule is being tuned. |
comment_sections.summary | bool | true | Show the top-of-comment summary block. |
comment_sections.cost_breakdown | bool | true | Show the per-resource cost diff table. |
comment_sections.monthly_spend | bool | true | Show the monthly spend total. |
comment_sections.optimization_tips | bool | true | Accepted so older files raise no unknown-field warning. It changes nothing: suggestions appear only inline on the diff, and code_suggestions_enabled turns those off. |
Limits
excluded_paths, excluded_resource_types and cloudformation.paths each take at most 100 globs of up to 256 characters. cloudformation.parameter_files takes at most 400 entries. The bot drops the rest and warns on the PR comment.
Glob syntax for excluded_paths, excluded_resource_types and cloudformation.paths
A * matches any run of characters, slashes included:
tests/fixtures/**matches every path undertests/fixtures/.aws_iam_*matches every Terraform resource type starting withaws_iam_.AWS::Lambda::*matches every CloudFormation Lambda type.examples/*.tfmatches every Terraform file underexamples/, in subdirectories too.
Without *, the bot matches the string exactly.
CloudFormation
A parameter takes the first value the bot finds:
- The file
cloudformation.parameter_filesmaps to the template parameter_overridesin thesamconfig.toml,samconfig.yamlorsamconfig.ymlin the template's directory, under thecloudformation.samconfig_envenvironment. Asamconfigapplies to the template itstemplate_filenames. With notemplate_file, it applies totemplate.yaml,template.ymlortemplate.jsonin its directory- The
Defaultthe template declares
A parameters file is JSON in the AWS CLI format or the CodePipeline template configuration format:
[
{ "ParameterKey": "InstanceType", "ParameterValue": "m7g.large" },
{ "ParameterKey": "Environment", "ParameterValue": "prod" }
]{
"Parameters": {
"InstanceType": "m7g.large",
"Environment": "prod"
}
}The region comes from region_override, then from the samconfig environment, then defaults to us-east-1. A nested stack takes the parameters its parent passes down and the parent's region.
The cost comment lists the values the bot had to assume under Assumptions. Pull request bot covers what the bot reads and what it cannot price.
Validation behavior
The bot validates .levelfour/config.yml on every PR.
| Situation | What the bot does |
|---|---|
An unknown field, at the top level or under comment_sections | Strips it silently from the parsed config, and reports it as a warning at the bottom of the PR comment |
| A type mismatch, for example a number where a bool is expected | Falls back to defaults for that field, and warns on the PR |
| No file | Uses all defaults. This is the expected state for most repos |
enabld: false leaves the bot enabled and commenting. Read the unknown-field warning on the PR comment before you assume a repo is silent.What this file does not control
- Whether LevelFour can read the repo. The GitHub App's repository access, set in your GitHub org settings, decides that. Even with
enabled: false, LevelFour still reads the Infrastructure-as-Code for the savings recommendations engine. To stop LevelFour reading a repo at all, remove it from the GitHub App installation. See GitHub onboarding. - PR creation by LevelFour. This file affects PRs your team opens. The savings PRs LevelFour opens come from the recommendation engine and ignore
enabled. - Check runs the dashboard executes. Cost recommendation runs from the dashboard ignore this file.
Next
- GitHub onboarding is how the app gets installed, and where you change which repos it can see
- GitHub Actions is a separate feature: calling the LevelFour API from your own CI workflows
GitHub Actions
Workflows that comment a cost summary on a pull request, run a scheduled cost check with the Python or TypeScript SDK, and upload a daily report as a build artifact.
CI/CD Integration
Gate a pull request on cloud cost with l4 estimate and l4 diff, using ready-made workflows for GitHub Actions and GitLab CI.