Resourcely Documentation
LoginSign Up
  • Get Started
    • 🎱What is Resourcely?
    • 👋Why Resourcely
    • 🏃Quickstart
      • Terraform policies integrated into CI
      • Remediate policy violations in existing infrastructure
      • Templates for generating Terraform
      • Glossary
  • Concepts
    • Foundry
      • Create Blueprints with Foundry
      • Creating Guardrails with Foundry
      • lmport Terraform Modules
    • Guardrails
      • Writing your own Guardrails
      • Editing Guardrails
      • Releasing Guardrails
      • Enabling Inactive Guardrails
      • Guardrails in Action
        • 🐱GitHub Actions
        • 🦊GitLab Pipelines
    • Campaigns
      • Get started with Campaigns
      • Creating Campaigns
      • Remediate Resources
      • Campaign Agent
        • State File Support
          • Amazon Simple Storage Service (S3)
          • Google Cloud Storage (GCS)
          • HCP Terraform
          • Spacelift
        • Running Campaigns with GitHub Actions and a Repo-Hosted State File
        • Running Campaigns Locally
    • Blueprints
      • Authoring Your Own Blueprints
      • Using Built-in Resourcely Blueprints
      • Configuring Global Contexts
      • Deep Linking
    • Resources
      • Provisioning Infrastructure
      • Editing Infrastructure
      • Shopping Cart
      • Config Roots and Environments
    • Other Features and Settings
      • Global Values
      • Global Context
      • Metrics
      • Resourcely-cli
      • Resourcely.yaml
      • VCS Proxy
      • Settings
        • User management
        • Company Information
        • Notification Settings
        • Change Management
          • 🐱Connect to GitHub
          • 🦊Connect to Gitlab
        • Generate API Token
    • ✨Production Setup
      • Single Sign-On (SSO)
        • Auth0
        • AWS Single Sign-On
        • Azure AD
        • Google Workspace
        • JumpCloud
        • Okta
        • Omnissa Workspace ONE (formerly VMware)
        • OneLogin
        • Ping Identity
        • Other SAML / OIDC Providers
      • Source Code Management
        • Page
        • 🐱GitHub
        • 🦊GitLab
        • Atlassian Bitbucket
        • Azure Repos
  • Tutorials and guides
    • Remediation Use Cases
      • Apply tags to resources for automating backups
      • Implement centralized logging
    • Blueprints Use Cases
      • Automate Data Pipeline Creation
      • Encryption for GCP
      • AWS Account Factory
      • Streamline and govern AI
      • IAM Factory
      • Cost optimization for FinOps
      • Guardrails for Terraform Modules
    • Using the Resourcely Terraform Provider
      • Setup Resourcely Provider
      • Blueprints
      • Guardrails
      • Global Context
  • Integrate
    • CI/CD & Terraform Runners
      • Atlantis
      • 🐟AWS CodeBuild
      • Azure Pipelines
      • Buildkite
      • CircleCI
      • CloudBees CI
      • Codefresh
      • Digger
      • Env0
      • 🎏GitHub Actions
        • 🐱Local Plan
          • 🐹AWS with OpenID Connect
        • 🐶Terraform Cloud Integration
      • 🦊GitLab Pipelines
      • Harness
      • 🗻HashiCorp Cloud Platform (formerly Terraform Cloud)
      • Jenkins
      • Octopus Deploy
      • Scalr
      • 🌌Spacelift
      • Terramate
      • 🌎Terrateam
    • Cloud Providers
      • 🌨️Amazon Web Services (AWS)
      • 🤓Google Cloud Platform (GCP)
        • Guardrail Gaunlet at Google Cloud Next 2025
      • 💾Microsoft Azure
      • Alibaba Cloud
      • Huawei Cloud
      • IBM Cloud
      • Oracle Cloud Infrastructure (OCI)
      • Tencent Cloud
      • VMware vSphere
    • Developer Portals
      • Atlassian Compass
      • Backstage
      • Cortex
      • Harness IDP
      • Home grown internal developer portals
      • OpsLevel
      • Port
      • Roadie
    • ITSM
      • Atlassian Jira
      • FreshWorks
      • ServiceNow ITSM
      • ZenDesk
    • CSPM
      • Wiz
    • More Terraform Provider Integrations
      • 🚂ConductorOne Provider
      • Databricks Provider
      • Kubernetes Provider
      • 🐕Datadog Provider
      • ❄️Snowflake Provider
Powered by GitBook
On this page
  • Running the CLI
  • JSON output
  • Advanced usage
  • Running resourcely-cli with many plans
  • Multiple runs of resourcely-cli
  • Pull request approval
  1. Concepts
  2. Other Features and Settings

Resourcely-cli

PreviousMetricsNextResourcely.yaml

Last updated 4 months ago

resourcely-cli is a command line utility that helps Resourcely evaluate against Terraform plans. It runs in on your infrastructure, typically a CI/CD runner, and only sends lightweight metadata about Guardrail violations back to Resourcely.

This page describes general resourcely-cli concepts that apply to any runner.

Running the CLI

resourcely-cli is available as a or as a . Individual users never need to run resourcely-cli manually. See for how to configure various CI systems to run resourcely-cli automatically.

JSON output

resourcely-cli can produce a JSON file with finding details. You can consume them in code that gathers statistics, sends slack messages, etc. Pass --output_file <filename> to enable this feature.

Here is an example file with comments describing each field:

{
  // Contains a list of all findings, including ones from evaluate-only guardrails
  "findings": [
    {
      "actions": {
        // PR approvals triggered by this finding
        "approval": {
          // The name of the Notification Group in resourcely
          "resourcely_team": "default",
          
          // The rest of the fields are properties of the Notification Group
          "github_reviewers": [
            "secops"
          ],
          "gitlab_reviewers": [],
        }
      },
      
      // The ID of the guardrail
      "guardrail_id": "787de9a7-8cd7-4dd7-8851-f88653ed0900",
      
      // A link to the guardrail's detail page
      "guardrail_link": "https://portal.resourcely.io/guardrails/5e89f370-f0f9-4e5f-95c0-4b0759c7b0a8",
      
      // The state of the guardrail at the time resourcely-cli ran. Values:
      // GUARDRAIL_STATE_ACTIVE
      // GUARDRAIL_STATE_EVALUATE_ONLY
      "guardrail_state": "GUARDRAIL_STATE_ACTIVE",
      
      // The part of the guardrail that was violated
      "requirement": "REQUIRE egress.from_port != 10",
      
      // The resource that violated the guardrail
      "resource": {
        "address": "aws_security_group.blah",
        "tf_config_root_path": "us-east-1",
        "environment": "dev",
        "actions": [
          "create"
        ]
      }
    }
  ]
}

Advanced usage

Below, we'll use the following resourcely.yaml in examples:

terraform_config_roots:
  - name: "Global resources"
    path: global
    # no environments for the sake of example
  - name: "Regional resources"
    path: regional
    environments:
      - name: dev
        tfvars_file: regional/dev.tfvars
      - name: prod
        tfvars_file: regional/prod.tfvars

Running resourcely-cli with many plans

You can run resourcely-cli with several plans at once. For each plan, you must specify the config root (and environment, if applicable). Resourcely uses these values to merge findings from each plan and determine when it can approve the pull request.

Note: The values of --config_root_path and --environment must match the corresponding path and name fields in resourcely.yaml.

Examples:

$ resourcely-cli <other args> \
  --config_root_path global --plan global.tfplan.json

$ resourcely-cli <other args> \
  --config_root_path regional --environment dev --plan regional-dev.tfplan.json \
  --config_root_path regional --environment prod --plan regional-prod.tfplan.json

You can pass --error_on_violations parameter to Resourcely-cli if you want it to exist with non-zero when it finds guardrail violations

IIf you use Terraform Cloud as a runner, you can specify the resourcely:environment: tag. For example, creating a tag in your Terraform Cloud workspace, such as resourcely:environment:dev, is equivalent to passing --environment dev in the CLI.

Multiple runs of resourcely-cli

Some CI/CD setups can't access every plan in one place, so they must run resourcely-cli multiple times. After each run of resourcely-cli, Resourcely will merge findings from that run over any prior findings, using the config root and (optionally) environment as the key.

An example for the sake of demonstrating the merge logic:

# Assume we ran the commands from the previous section. There were 9 findings:
# 1 in global, 3 in regional-dev, and 5 in regional-prod.

# The developer fixes 3/3 regional-dev findings, and 2/5 regional-prod findings.
# Your CI job then runs resourcely-cli for dev and prod separately.

$ resourcely-cli <other args> \
  --config_root_path regional --environment dev --plan regional-dev.tfplan.json

# This run replaced the 3 regional-dev findings with zero findings. There are now
# 6 findings total - 1 in global and 5 in regional-prod.

$ resourcely-cli <other args> \
  --config_root_path regional --environment prod --plan regional-prod.tfplan.json

# This run replaced the 5 regional-prod findings with the 3 un-fixed findings. There
# are now 4 findings total - 1 in global and 3 in regional-prod.

You can pass --output_file to write findings to a file (as json)

Pull request approval

When a pull request is created, Resourcely computes the set of plans that it expects to receive findings from. Resourcely will only approve the pull request once it has received findings from every plan for the PR's latest commit.

Resourcely computes the set of expected plans based on which files the pull request has changed:

  • If the PR changes a .tf file in a config root...

    • ...if that config root does not have environments, Resourcely expects one plan from it.

    • ...otherwise, Resourcely expects one plan from each of its environments.

  • Additionally, if the PR changes a .tfvars file listed in resourcely.yaml, Resourcely expects one plan from that config root and environment.

Examples:

Files changed: global/main.tf, regional/main.tf
3 expected plans: global (no env), regional dev, regional prod

# Note the change to main.tf. Resourcely will expect a plan from both envs, even
# though only one env's tfvars changed.
Files changed: regional/main.tf, regional/dev.tfvars
2 expected plans: regional dev, regional prod

Files changed: regional/prod.tfvars
1 expected plans: regional prod

If you use to define multiple config roots (and optionally, environments), you probably need to use resourcely-cli to evaluate multiple plans, one per config root (and environment).

Guardrails
Docker container
self-contained binary
CI/CD & Terraform Runners
.resourcely.yaml