# Welcome to Firefly Documentation

Welcome to the Firefly Docs, your go-to resource for understanding, configuring, and optimizing Firefly's Automated Cloud Resilience platform.

## What is Firefly?

Firefly is the Automated Cloud Resilience platform that helps enterprises instantly recover from outages and cyberattacks using Infrastructure-as-Code.

Firefly's AI agents continuously scan your cloud footprint, maintain a real-time system of record, remediate drift, and keep your infrastructure governed and recovery-ready. When incidents strike, Firefly restores full environments in minutes, helping organizations meet strict RTO requirements and maintain audit-ready evidence for DORA, SOC 2, ISO, and more.

Firefly's platform is built around three core capabilities:

* **Automate** — Accelerate infrastructure delivery by standardizing IaC workflows through GitOps with built-in guardrails, and empower teams with on-demand self-service provisioning using reusable infrastructure blueprints.
* **Govern** — Scan your entire cloud and maintain a real-time System of Record with continuous event streaming, full dependency mapping, IaC coverage tracking, drift detection, and AI-powered remediation.
* **Recover** — Automatically rebuild full environments with all dependencies in minutes. Confidently roll back across regions and accounts with no manual runbooks, and maintain audit-ready evidence for DORA, SOC 2, and ISO compliance across your entire multi-cloud environment.

## Who is this Documentation For?

This documentation is designed for engineering, security, and leadership roles across modern cloud organizations:

* **Platform Engineers & DevOps Teams** — Automate IaC workflows, enable self-service provisioning, and integrate with existing CI/CD pipelines.
* **SREs & Reliability Engineers** — Implement drift detection, automated remediation, and instant environment recovery to meet RTO targets.
* **Security & Compliance Teams** — Enforce guardrails and policy packs, ensure clean-region recovery, and maintain continuous audit-ready compliance evidence.
* **CCoE & Cloud Leaders** — Drive consistent DR policies with auditable, automated resilience across all teams and environments.
* **CIO / CTO & Decision Makers** — Prove recoverability, minimize outage impact, and operate resilient infrastructure at scale.

## Key Capabilities

Firefly addresses the full spectrum of cloud resilience challenges, from daily operations to large-scale incident recovery:

* **Cloud Scanning & Discovery** — Continuously scan your cloud footprint and maintain a real-time System of Record with full dependency and relationship mapping across all resources.
* **IaC Coverage & Codification** — Track codified vs. ungoverned resources and automatically convert unmanaged infrastructure into standardized, reusable Terraform or OpenTofu.
* **Infrastructure Backup & Disaster Recovery** — Capture continuous snapshots with full dependency graphs and restore complete environments into clean regions or accounts in minutes.
* **Drift Detection & Remediation** — Continuously detect configuration drift between IaC and real cloud state, and remediate using AI agents to keep infrastructure aligned and stable.
* **Unified Governance & Compliance** — Enforce security, compliance, and cost policies across your entire cloud footprint, with audit-ready evidence for DORA, SOC 2, ISO, and PCI.
* **Cost Optimization** — Identify and eliminate cloud waste with actionable insights across your entire multi-cloud infrastructure.

## What You'll Find Here

This documentation is structured into key sections, making it easy to find what you need:

* [**Introduction**](/introduction/what-is-firefly) – Learn about Firefly's features, benefits, and how it works.
* [**Getting Started**](/getting-started/account-setup-and-onboarding) – How to set up Firefly, onboard cloud accounts, and navigate the platform.
* [**Terminology**](/introduction/terminology) – A glossary of Firefly-specific terms (ClickOps, Codified Assets, IaC Coverage, Drift, etc.).
* [**Cloud Asset Inventory**](/detailed-guides/cloud-asset-inventory) – Learn how Firefly categorizes assets, detects unmanaged resources, and improves IaC coverage.
* [**IaC Explorer**](/detailed-guides/iac-explorer) – Explore Terraform state files, modules, and providers to visualize your IaC landscape.
* [**Event Center**](/detailed-guides/event-center) – Audit ClickOps changes, mutation events, and ownership tracking in real-time.
* [**Codification**](/detailed-guides/codification) – Automatically generate Terraform, Pulumi, CloudFormation, and Kubernetes manifests for unmanaged assets.
* [**Policy & Governance**](/detailed-guides/policy-and-governance) – Create custom policies and review your compliance posture across your cloud environment.
* [**Integrations**](/integrations/overview) – Step-by-step guides on integrating Firefly with CI/CD pipelines, project management tools, and DevOps platforms.
* [**Workflows & Guardrails**](/detailed-guides/workflows) – Find solutions for automating processes and implementing protective measures.
* [**API**](/general-information/api/auth) – Learn how to use Firefly's API to automate tasks and integrate with other tools.

## Get Started with Firefly

To begin using Firefly, check out our [Getting Started Guide](/getting-started/account-setup-and-onboarding) and [Detailed Guides](/detailed-guides/dashboard-overview), which will walk you through:

1. Signing up & logging into Firefly.
2. Connecting your cloud accounts (AWS, Azure, Google Cloud, Kubernetes, etc.).
3. Discovering unmanaged assets & improving your IaC coverage.
4. Setting up governance rules & compliance checks.
5. Exploring Firefly's analytics and cost insights.

## Need Help?

If you have questions or encounter issues, you can reach out to us through:

* **Support & Help Center** – Browse [troubleshooting guides](/troubleshooting-and-faqs/common-issues) and [FAQs](/troubleshooting-and-faqs/faqs).
* **Contacting Support** – Check out our [contacting support](/general-information/contacting-support) guide.
* **In-App Chat** – Use the Firefly web app chat (bottom-right corner) for quick assistance.

🚀 Let's get started and take control of your cloud infrastructure with Firefly!


# What is Firefly?

Firefly is a cloud infrastructure automation platform that enables platform and DevOps teams to automate, manage, and govern their entire cloud footprint with Infrastructure-as-Code (IaC).

Acting as a central "source of truth" for your cloud, Firefly discovers and tracks resources across AWS, Azure, Google Cloud, Kubernetes clusters, and SaaS platforms. By providing a unified configuration management database (CMDB) for dynamic cloud environments, Firefly empowers teams to finally uncomplicate their cloud operations.

With streamlined IaC orchestration, and unified asset management, Firefly helps organizations:

* Manage IaC across multiple providers with a unified interface.
* Orchestrate infrastructure deployments with ease.
* Automatically codify existing infrastructure.
* Detect and remediate configuration drifts in real-time.
* Enforce governance policies across the entire cloud environment.
* Reduce waste and prevent outages.
* Accelerate innovation while maintaining security and performance at scale.

Delivered as a SaaS platform, Firefly integrates seamlessly with your cloud accounts, Kubernetes clusters, version control systems, and ChatOps tools with no local installation required.


# Who is Firefly for?

Firefly is designed for DevOps, SRE (Site Reliability Engineering), Platform Engineering, and Cloud Infrastructure teams. If you are responsible for managing cloud resources, implementing IaC, ensuring compliance, or optimizing cloud costs, Firefly is built for you. Typical users include:

* **DevOps Engineers & SREs**: to streamline cloud provisioning and eliminate manual config drift.
* **Platform Engineering Teams**: to provide self-service infrastructure and enforce best practices enterprise-wide.
* **Cloud Architects & IT Ops**: to gain visibility into multi-cloud assets and maintain an authoritative inventory.
* **Security/Compliance Engineers**: to implement policy-as-code checks for security, compliance, and governance.
* **FinOps or Cloud Cost Managers**: to identify wasteful resources and enforce cost optimization policies.

In short, any team that needs to manage complex cloud environments at scale – while keeping them secure, compliant, and cost-effective – can benefit from Firefly.


# Why use Firefly?

Modern cloud environments are increasingly complex, and organizations face many challenges that Firefly is designed to solve. Here are the key benefits and problems Firefly addresses:

## Unified Visibility & Inventory

Eliminate fragmented views by discovering all cloud assets (across accounts, regions, and providers) in one place. This holistic visibility replaces "blind spots" with a single source of truth, making it easy to find orphaned instances, forgotten databases, or unmanaged resources lurking in your cloud.

## Infrastructure-as-Code Consistency

Minimize manual, error-prone configuration work by automating IaC. Firefly can transform ad-hoc cloud resources into code and manage them via version control, ensuring every change is tracked and follows best practices. This consistency reduces configuration drift and keeps environments stable.

## Infrastructure-as-Code Orchestration

Streamline your infrastructure deployment process by leveraging your existing CI/CD pipelines to automate your infrastructure code. Firefly's IaC orchestration capabilities allow you to provision, manage, govern infrastructure and also enforce organization practices within your established workflows.

## Drift Prevention & Rapid Remediation

Prevent the "silent killer" of cloud infrastructure – configuration drift – from causing issues. Firefly continuously monitors your cloud for changes that deviate from the desired (codified) state and alerts you immediately. With Firefly drift remediation, it not only flags problems but can also generate one-click fixes to resolve drifts or misconfigurations before they lead to downtime.

## Policy Compliance & Governance

Avoid security gaps and compliance violations by enforcing Policy-as-Code. Firefly lets you define and apply rules (for security, cost, tagging, etc.) across all environments. It comes with built-in policies for standards like PCI-DSS, SOC 2, HIPAA, and more, and ensures things like encryption, proper access control, and resource tagging are consistently in place. Non-compliant resources are flagged instantly so you can address them before they pose a risk.

## Cost Control & Optimization

Gain cost visibility and reduce cloud waste. Firefly tracks the cost of each resource and identifies unused or underutilized assets (e.g., unattached volumes, idle VMs) that drive up your bill. By highlighting these and even automating their cleanup, Firefly helps cut unnecessary spend and improve cost-efficiency.

## Increased Productivity with AI & Automation

By automating tedious tasks (like writing IaC or cleaning up resources) and providing an AI Assistant for queries and recommendations, Firefly frees up engineering time. Teams can focus on innovation rather than manual inventory tracking or firefighting issues. The AI Assistant can answer questions in plain English about your infrastructure and provide insights or best-practice suggestions on the fly.

***

In summary, Firefly brings order, visibility, and control to cloud operations. It's a one-stop solution to manage your cloud via code, keep configurations in sync, enforce governance, and optimize costs – ultimately making your cloud environment more reliable, secure, and efficient.


# Terminology (Glossary)

This section provides a comprehensive list of all key terms used in Firefly. Understanding these terms will help you navigate the platform and make the most of its features.

## General Terms

### Asset

A cloud resource that Firefly discovers in your environment, such as an AWS EC2 instance, an Azure VM, or a Kubernetes cluster. Assets can be unmanaged, codified, drifted, or ghost assets, depending on their relationship with Infrastructure-as-Code (IaC).

### Unmanaged Asset

A cloud resource that was created manually (via ClickOps) and is not currently managed by any Infrastructure-as-Code (IaC) tool. Unmanaged assets can be codified to bring them under IaC management.

### Codified Asset

A cloud resource that is fully managed using Infrastructure-as-Code. Firefly detects that the resource has an associated Terraform/Pulumi/CloudFormation definition.

### Drifted Asset

A resource that was initially created and managed via IaC but has since been manually modified. Drift means the current cloud configuration does not match the original definition in code.

### Ghost Asset

A resource that exists only in the IaC state file but no longer exists in the cloud. This happens when an IaC-managed resource is deleted outside of the IaC workflow, leaving a stale record in the Terraform state file.

### Pending Asset

This status is temporary. The asset is still in the process of being analyzed, and Firefly has not yet determined its IaC status. In other words, the asset is in a waiting state until Firefly finishes scanning and classifying it.

### Undetermined Asset

Firefly was unable to determine the asset's IaC status. This can happen if Firefly has partial information about the asset but cannot fully match it to an IaC state or definition. For example, Firefly might detect the resource in an IaC file but not be able to find it via cloud scanning (or vice versa), making its status unclear. An undetermined asset could potentially be codified, drifted, or unmanaged – but the platform isn't certain due to missing data or an unsupported resource type.

### IaC-Ignored Asset

The asset has been manually marked to be ignored in Firefly's IaC tracking. Assets with this status were unmanaged but a user created an IaC-Ignore rule to exclude them from IaC coverage. They will not count toward "unmanaged" asset counts or appear in codification suggestions. (Common examples are default cloud resources that you decide to ignore in the platform.)

### Child Asset

A resource that is part of a larger codified module or stack but isn't independently codified on its own. In Firefly, a "child" asset is managed by its parent resource's IaC definition. For example, an AWS EBS volume that is automatically created as part of an EC2 instance is considered a child asset – it's managed through the EC2's configuration, not directly by separate IaC code. Child assets don't need their own IaC because they are created and managed by the parent's IaC.

## ClickOps & Event Tracking

### ClickOps

Refers to the manual creation or modification of cloud resources using a cloud provider's web console. Firefly detects ClickOps changes and flags them as unmanaged or drifted assets.

### CLI/SDK Event

Refers to the creation or modification of cloud resources using a cloud provider's CLI, SDK, or API.

### Mutation Event

Any detected change to an infrastructure resource, whether manual (ClickOps, CLI, or SDK) or automated (via CI/CD, Terraform, or API). Mutation events provide a detailed log of configuration changes, including what was modified and by whom.

### Event Center

A Firefly feature that provides a timeline-based view of all mutation, ClickOps, and CLI/SDK events, allowing users to track changes, detect unauthorized modifications, and audit infrastructure changes. Learn more in [Event Center](/detailed-guides/event-center).

### Ownership Attribution

Firefly tracks who made a change to an asset through multiple sources: cloud logs (AWS CloudTrail, Azure Activity Logs, Google Cloud Audit Logs) for IAM users, roles, or service accounts; and Git blame information for changes made through IaC.

## Infrastructure-as-Code (IaC)

### IaC (Infrastructure-as-Code)

A methodology for managing cloud infrastructure using code-based configurations (e.g., Terraform, Pulumi, CloudFormation) instead of manual processes. Firefly integrates with multiple IaC frameworks to help users achieve better governance and automation. Learn more in [Infrastructure-as-Code Automation](/key-features/infrastructure-as-code-automation).

### IaC Coverage

A metric that indicates the percentage of assets managed by Infrastructure-as-Code. A higher IaC coverage means fewer ClickOps/manual changes.

### IaC Explorer

A Firefly feature that provides visibility into IaC stacks, Terraform modules, and providers used across your cloud environment. It helps users understand how infrastructure is structured in code. Learn more in [IaC Explorer](/detailed-guides/iac-explorer).

### Terraform State File (.tfstate)

A JSON file that stores the current state of Terraform-managed infrastructure. Firefly reads state files to determine which resources are codified and which are unmanaged or ghost assets.

### Blast Radius

The scope of impact when making a change in Terraform or another IaC tool. Firefly's Blast Radius Analysis helps assess how updates to Terraform modules might affect large parts of an infrastructure.

### Codification

The process of converting unmanaged cloud resources into Infrastructure-as-Code. Firefly automatically generates Terraform/Pulumi/CloudFormation code to bring unmanaged resources under IaC control. Learn more in [Codification](/detailed-guides/codification).

### Advanced Codification

A Firefly capability that allows for modularized codification by generating IaC modules instead of flat configurations. It supports module creation, module calls, dependency handling, and cloud migrations between AWS, Azure, and Google Cloud.

### Module Creation

Instead of generating a one-time resource definition, Firefly can structure codified assets into reusable Terraform modules, ensuring better maintainability.

### Module Call Codification

Firefly recognizes existing Terraform modules in your repositories and able to codify discovered resources with them, improving standardization and reusability.

### Drift Remediation

Firefly's ability to detect and automatically fix drifted resources by either reapplying the IaC definition or regenerating the correct Terraform code for manual review. Learn more in [Drift Detection & Remediation](/key-features/drift-detection).

## Governance & Compliance

### Policy Packs

Predefined security and compliance rules that Firefly applies to IaC configurations and cloud assets. Policies can enforce tagging conventions, network security settings, and best practices. Learn more in [Policy & Governance](/detailed-guides/policy-and-governance).

### Cost Optimization Insights

Firefly analyzes your cloud infrastructure for unused or overprovisioned resources, helping reduce cloud spending. Learn more in [Cost Visibility & Optimization](/key-features/cost-optimization).

## Workflows & Guardrails

### Workflows

Automated Infrastructure-as-Code (IaC) orchestration processes within Firefly that help enforce governance and security. Workflows can orchestrate IaC operations, apply policy checks, remediation actions, and compliance rules across your cloud environments during IaC operations. Learn more in [Workflows & Guardrails](/detailed-guides/workflows).

### Guardrails

A Firefly feature that enforces cloud cost, security, and compliance at the provisioning stage by preventing misconfigured infrastructure from being deployed. Learn more in [Creating Guardrail Rules](/detailed-guides/workflows/creating-guardrail-rules).

### Projects

A project is an organizational unit in Firefly for grouping and managing related resources like workspaces, variable sets, and self-hosted runners. It acts as a boundary for access control, allowing teams to manage their infrastructure independently.

### Variable Set

A variable set is a reusable collection of variables that can be shared across workspaces and projects. This allows for consistent configuration and secrets management, with a clear hierarchy of precedence.

### Workspace

A workspace is the primary execution environment for IaC operations in Firefly. It holds all the necessary configurations for a given set of infrastructure, including VCS settings, variables, and runner details. Workspaces can be organized within Projects or be global.

### Runners

Execute Terraform/OpenTofu/Terragrunt operations (plan/apply) within Firefly. There are two types:

* **SaaS Runners**: Fully managed by Firefly and run in Firefly's cloud environment.
* **Self-Hosted Runners**: Customer-managed agents that run within the customer's own infrastructure for secure access to internal resources.

### FireflyCI

The binary used for Firefly CI/CD integration that is used to enforce IaC policies during pipeline runs in a third-party CI/CD tool. An alternative for the Firefly Runners.

## Integrations

### Data Source Integrations

Firefly connects with AWS, Azure, Google Cloud, Kubernetes, and SaaS platforms (Datadog, GitHub, etc.) to fetch real-time configuration data. Learn more in [Integrating Data Sources](/integrations/data-sources).

### Version Control Integrations

Firefly integrates with your GitHub, GitLab, Bitbucket, and other VCS providers to index IaC repositories data and to enable GitOps workflows. Learn more in [Integrating Version Control](/integrations/version-control).

### CI/CD Integration

Firefly integrates with GitHub Actions, GitLab CI, and other CI/CD tools to enforce IaC policies during pipeline runs (via FireflyCI). Learn more in [Integrating Workflows with CI/CD](/integrations/workflows).

### Notification Integrations

Firefly can integrate with Slack, Microsoft Teams, and other notification platforms to send alerts and updates. Learn more in [Integrating Notifications](/integrations/notifications).

### IaC Remote State Integrations

Firefly integrates with Terraform Cloud, Terraform Enterprise, and other IaC backends to fetch IaC remote state data. Learn more in [Integrating IaC Remote State](/integrations/iac-remote-state).

### Project Management Integrations

Firefly can integrate with project management platforms such as Jira to generate tickets for unmanaged assets, policy violations and more. Learn more in [Integrating Project Management](/integrations/project-management).

***

This glossary ensures you understand all Firefly terminology used throughout the platform. By becoming familiar with these terms, you'll be able to fully utilize Firefly's governance, compliance, and automation capabilities.


# Infrastructure-as-Code Automation

Infrastructure-as-Code Automation in Firefly enables you to automate the creation and management of cloud resources via code. Instead of manually writing Terraform scripts or clicking around cloud consoles, Firefly can generate IaC for you and integrate with your code repositories. This capability accelerates IaC adoption and ensures your cloud deployments are repeatable and auditable.

## Key aspects of Firefly's IaC Automation

### Auto-Generate IaC ("Codify")

Firefly can automatically generate Terraform, OpenTofu, Terragrunt, Pulumi, CloudFormation, Helm and other types of IaC for existing cloud resources. For example, if you have a manually-created S3 bucket or VM, Firefly will discover it and propose equivalent code to manage it. The tool handles dependencies as well – e.g. if an EC2 instance requires a VPC or Security Group, those will be included in the generated config.

### Bring Unmanaged Resources Under Control

Firefly identifies resources that are not yet managed as code and lets you codify them with one click. This turns "shadow IT" infrastructure into code that is version-controlled and part of your standard provisioning process. You can choose to output a new Terraform file or merge into an existing one, making adoption flexible.

### Best-Practice Templates

The generated IaC follows industry best practices (naming conventions, tagging, etc.), so you get clean, readable code. This saves countless hours for engineers and avoids mistakes – Firefly ensures the output is consistent and compliant with your standards out-of-the-box.

### Git Integration

You can commit the generated code directly to your Git repository through Firefly, optionally via a Pull Request for review. This means your IaC changes enter your normal code review and pipeline (GitOps) process.

### Self-Service Infrastructure

With these automation capabilities, platform teams can enable developers to request or provision infrastructure through Firefly's interface. Firefly will handle generating the necessary IaC, so less experienced users can get infrastructure they need without direct cloud access, speeding up delivery with proper guardrails in place.

For example, if an AWS S3 bucket was created manually in your account, Firefly can generate the Terraform code with the `import` block to manage that bucket going forward. A sample Terraform resource snippet generated by Firefly might look like this:

```hcl
# Example Terraform code for an AWS S3 bucket, generated by Firefly
resource "aws_s3_bucket" "my_app_bucket" {
  bucket = "my-app-bucket"
  acl    = "private"
  tags = {
    Environment = "production"
    Owner       = "team-alpha"
  }
}

# Import the existing S3 bucket into Terraform
import {
  to = aws_s3_bucket.my_app_bucket
  id = "my-app-bucket"
}
```

In this snippet, Firefly has identified an existing S3 bucket and produced the Terraform configuration to manage it. The `import` block is a crucial part of this process - it tells Terraform to associate the existing S3 bucket in your cloud with the resource definition in your code. This is necessary because the bucket was created manually outside of Terraform, and we need to bring it under Terraform's management. You could save this code into your Terraform files, and from then on, any changes to the bucket should be made through code (ensuring consistency). Firefly can perform similar codification for resources in Azure, Google Cloud, Kubernetes (Helm charts), etc., allowing you to manage all infrastructure in a unified way.

### Next Step: IaC Orchestration

Once you have generated IaC code through Firefly's automation capabilities, the next step is deploying and managing that infrastructure. Firefly's [Infrastructure-as-Code Orchestration](/key-features/infrastructure-as-code-orchestration) provides automated workflows, policy enforcement, and governance for your IaC deployments, ensuring your generated code is deployed safely and consistently across your environments.


# Infrastructure-as-Code Orchestration

Infrastructure-as-Code Orchestration in Firefly provides automated management and governance for your Terraform, OpenTofu, and Terragrunt deployments. While [Infrastructure-as-Code Automation](/key-features/infrastructure-as-code-automation) handles the generation and codification of IaC, orchestration manages the entire deployment lifecycle with workflows and policy enforcement.

## Key Capabilities of IaC Orchestration

### Automated Workflows

Firefly Workflows automate your IaC deployment process by connecting to your Git repositories and executing `plan` on pull requests and `apply` on merge. Each workflow is tied to a workspace that includes your IaC code, variables, execution environment, and deployment history. This eliminates manual deployment steps and ensures consistent, repeatable infrastructure changes.

### Policy Enforcement with Guardrails

Firefly Guardrails provide automated policy enforcement by evaluating `plan` outputs against predefined rules. These rules can control costs, enforce security policies, manage resource permissions, and ensure compliance standards. Guardrails integrate with [Policy-as-Code](/key-features/policy-as-code) capabilities to block non-compliant deployments before they reach your infrastructure.

### Flexible Deployment Options

Firefly supports multiple deployment models:

* **Firefly-Managed**: Turnkey solution with secure, managed runners.
* **Self-Hosted Runners**: Execute within your network boundaries.
* **CI/CD Integration**: Enhance existing pipelines with visualization and governance.

### Organizational Structure

Projects provide organizational boundaries with role-based access control, while Variable Sets enable centralized configuration management. This hierarchical structure supports complex multi-team environments with proper isolation and variable inheritance.

## Benefits

* **Automated Deployments**: Reduce manual effort and eliminate human errors.
* **Policy Compliance**: Ensure all changes meet organizational standards before deployment.
* **Audit Trail**: Complete visibility into deployment history and decisions.
* **Team Collaboration**: Integrate with existing VCS and chat workflows.
* **Risk Mitigation**: Prevent security breaches and cost overruns through automated checks.

For detailed implementation guides, refer to the [Workflows documentation](/detailed-guides/workflows).


# Cloud Asset Inventory

Firefly provides a Cross-Cloud Asset Inventory that gives you complete visibility into all your cloud resources and their IaC status. This feature is essentially your real-time cloud inventory dashboard, acting as an always up-to-date CMDB. As Firefly connects to your cloud accounts, Kubernetes clusters, and SaaS services, it continuously discovers resources and updates their information.

## How the Inventory works and what it offers?

### Comprehensive Multi-Cloud View

In a single pane, you can see resources across AWS, Azure, Google Cloud, Kubernetes, and SaaS services like Okta, Datadog, Cloudflare, etc. Firefly normalizes data from all these sources into one searchable inventory. No more switching between AWS Console, Azure Portal, Google Cloud GUI – everything is aggregated.

### IaC Status & Classification

Every resource in the inventory is tagged with its IaC status:

* **Codified** (managed by IaC and in sync)
* **Drifted** (was managed by IaC but has deviated)
* **Unmanaged** (created outside IaC)
* **Ghost** (exists in code or state file but missing in cloud)
* **IaC-Ignored** (resource is unmanaged but is not counted as unmanaged)
* **Undetermined** (Firefly unable to determine the IaC status, or the resource is not supported yet)

These labels let you instantly pinpoint resources that need attention. For example, you can filter to find all unmanaged assets (which you may want to codify) or all drifted ones (which you need to fix).

### Rich Metadata & Search

Each resource entry is enriched with metadata like owner, cloud account, region, resource type, tags, configuration details, and even links to the IaC code and Terraform state managing it (if applicable). You can search and filter by any of these attributes. For instance, you might filter for `Resource Type: aws_instance` and `Tag: environment=dev` to list all dev EC2 instances. Firefly's robust search and filtering make it easy to slice and dice the inventory to find exactly what you need.

### Relationship Mapping

Firefly Inventory understands relationships between resources. You can select a resource and see related components (for example, an EC2 instance's attached volumes, or a Kubernetes pod's parent deployment). In the UI, Firefly can even show architecture diagrams mapping these connections, helping you comprehend complex architectures at a glance.

### Mutations, Events & Traceability

For each resource, you can view historical changes and events. Firefly keeps an event log of modifications (e.g., if a security group rule changed or a tag was updated). Moreover, because it links resources to IaC, you can trace a resource back to the exact Terraform module and Git repository that created it. This traceability is extremely useful—if someone asks "where did this resource come from?", Firefly can point you to the code and commit that created it.

### Custom Views & Reports

You can save custom filtered views of the inventory. For example, a view for "Production AWS untagged resources" or "K8s clusters and nodes in EU region" can be saved for quick access. These views update in real-time as inventory changes. Additionally, Firefly's inventory data can be exported (JSON/CSV), so you can share summaries of your cloud assets with stakeholders.

***

Behind the scenes, Firefly continuously scans your environment to keep the inventory current. Unlike manual asset tracking or point-in-time audits, the inventory is real-time. New resources are discovered within minutes, and any changes (drifts, new tags, deletions) are reflected. This means you always have an up-to-date picture of your cloud.

By using Cloud Asset Inventory, you gain confidence that nothing in your cloud is "unknown" or overlooked. It lays the groundwork for governance and optimization by first answering: What do we have out there? The Cloud Asset Inventory provides that answer at your fingertips, anytime.


# Drift Detection & Remediation

Drift Detection is one of Firefly's core strengths. Drift occurs when the actual state of a resource in the cloud diverges from the desired state defined in your IaC configuration. For example, a team member might manually open a port in a firewall, or change an instance type through the console, creating a mismatch between code and reality. Firefly continuously monitors for such drifts across your infrastructure and alerts you as soon as they detected.

## Key capabilities for drift management:

### Real-time Drift Alerts

Firefly detects configuration drift in real-time (via event-driven hooks and periodic scans). The moment a resource's live configuration deviates from what's in the IaC definition, Firefly flags a drift. You can receive instant notifications through your preferred channels (Slack, Microsoft Teams, PagerDuty, etc.) thanks to [Firefly's ChatOps integration](/integrations/notifications). This proactive alerting lets you address issues before they escalate.

### Drift Insight & Visualization

In the Firefly console, drifted resources are clearly indicated (with a "drifted" status and highlight). For each drift, Firefly shows the difference between the actual state and the IaC state. For example, it might display that a security group rule is open in AWS (actual) whereas your Terraform expects it closed. This side-by-side diff or summary makes it easy to understand what changed.

### Remediation Suggestions

Firefly doesn't stop at telling you what drifted – it helps you fix it. Firefly generates context-specific remediation steps or code to resolve the drift. In many cases, it will produce the exact Infrastructure-as-Code changes needed to bring the system back in sync. These could be Terraform code adjustments or CLI commands. For instance, if an EC2 instance type was changed manually, Firefly could suggest the Terraform code update (or a terraform plan to change it back).

### One-Click or Automated Fixes

With Firefly's remediation feature, you can apply fixes with minimal effort. After reviewing the suggested fix, you might choose to auto-apply it. Firefly can open a Pull Request to your Git repo with the necessary code changes to match the live state (or vice versa). This keeps the remediation under version control. Alternatively, for immediate issues, you might copy a CLI command from Firefly to quickly revert a change. Either way, Firefly's guided remediation turns hours of manual editing into a single-click resolution.

## How remediation works in practice

Suppose your Terraform config declares an EC2 instance with type `t2.micro` and `2` CPU threads per core, but someone manually changed it to `t2.nano` with `1` CPU thread per core directly in the AWS console. Firefly will detect this drift (e.g., `instance_type = t2.nano` in AWS vs `t2.micro` in code, and `cpu_threads_per_core = 1` in AWS vs `2` in code) and alert you. In the Firefly UI, you'd see the EC2 instance marked as drifted with details of these mismatches. Firefly would then generate a fix – in this case, it might be a Terraform code snippet to update the instance configuration to `t2.nano` and `1` CPU threads per core, or a `terraform apply` command to revert the changes. You could then have Firefly commit that Terraform code change to Git, and run your pipeline to sync the state. Within minutes, the drift is resolved and your code and cloud are back in sync, without manually writing any code or logging into the console.

<figure><img src="/files/CQtf35zunQJYVrECJCt0" alt="Drift details view showing configuration differences between IaC and actual state"><figcaption><p>Drift details view showing configuration differences between IaC and actual state</p></figcaption></figure>

<figure><img src="/files/w9aZywY6jkYnqOu2fMfJ" alt="Drift remediation interface with suggested fixes"><figcaption><p>Drift remediation interface with suggested fixes</p></figcaption></figure>

***

Drift Detection and Remediation maintain alignment between your infrastructure's actual state and its intended configuration in code. This proactive approach helps prevent service disruptions by identifying unauthorized modifications early, while also ensuring your infrastructure remains compliant with organizational policies and security standards.


# Policy-as-Code for Compliance & Governance

Firefly includes a powerful Policy-as-Code engine that allows you to define and enforce governance rules across your cloud environment. Policy-as-Code means that policies (security rules, compliance requirements, cost controls, etc.) are expressed in code or configuration files, rather than in ad-hoc manual checks. This approach ensures consistent, automated enforcement of best practices and standards. In Firefly, policies can cover a wide range of checks, from requiring certain tags on every resource, to ensuring no S3 bucket is public, to enforcing cost optimization on certain resources.

## Key capabilities of Firefly's governance and compliance features:

### Unified Policy Engine

Firefly provides a single policy enforcement framework that works across all your clouds and IaC tools. Instead of dealing with separate policy systems for AWS, Azure, Google Cloud, and Kubernetes, you can define policies once and apply them everywhere. Firefly integrates with cloud APIs and scanning tools to evaluate your infrastructure against these rules continuously.

### Pre-Built Compliance Rules

Out of the box, Firefly comes with a library of common policies and standards. These include templates for industry compliance frameworks like PCI-DSS, SOC 2, HIPAA, and others. For example, there are pre-built rules to ensure encryption is enabled on databases, that no databases are publicly accessible, that all resources have an owner tag, etc. Using these built-in policies, you can quickly achieve baseline compliance without writing everything from scratch. Firefly keeps these updated as standards evolve.

### Custom Policy-as-Code

You can also create custom policies specific to your organization using multiple approaches:

**No-Code Policy Builder**: Create governance rules without writing code using Firefly's intuitive no-code interface. Choose from attribute-based flows (checking resource properties like encryption status) or tags-based flows (enforcing tagging requirements). This approach is ideal for security and compliance teams who want quick policy creation without coding expertise.

**Rego Policy Language**: For advanced use cases, Firefly supports defining policies in code using the Open Policy Agent's Rego language. This means you can encode any rule (no matter how specific) into Firefly's engine. For instance, you might require that all EC2 volumes are encrypted with a particular KMS key, or that certain naming conventions are followed.

### Continuous Compliance Monitoring

Firefly continuously scans your asset inventory against all active policies. If a resource violates a policy, it's immediately flagged. The Governance page shows the overall compliance score (e.g., "95% of resources compliant, 5% with violations") and list out each violation. You can drill down to see which rule was broken and which resource is non-compliant. This real-time monitoring means you are always audit-ready.

### Violation Alerts & Remediation

Firefly can alert you when a policy violation is detected (via email or ChatOps) thanks to [Firefly's ChatOps integration](/integrations/notifications). Moreover, many policy violations can be fixed with automation. Firefly's AI assistant can suggest remediation steps for policy violations. For example, if a VM is found with an open SSH port against policy, Firefly suggests a Terraform code snippet (on managed assets) to close it, or a command (on unmanaged assets) to update the security group.

### Categorization and Reporting

Firefly organizes policy checks into intuitive categories like security, cost, reliability, tagging, etc. This helps you focus efforts (maybe start with critical security fixes, then improve tagging hygiene). The platform provides compliance reports that can be exported or shared, useful for governance meetings or audits, to demonstrate adherence or track improvements over time, learn more in the [Analytics Page](https://github.com/gofireflyio/product-docs/blob/main/analytics-&-reporting/using-analytics.md).

To illustrate a custom policy, here's a simple example of a Policy-as-Code rule written in Rego (the policy language for Open Policy Agent) that could be used in Firefly. This policy ensures every EC2 instance has an "Environment" tag and flags those that do not:

```rego
firefly {
  not input.tags["Environment"]
}
```

In this snippet, the policy logic evaluates the condition `not input.tags["Environment"]`. If this condition is true (meaning the "Environment" tag is not set on the input resource), Firefly will flag the resource as violating the policy. When adding this custom policy in Firefly, you would specify the resource type it applies to (e.g., EC2 instances). Firefly's policy engine would then evaluate this rule against all resources of the configured type. Any such resource without the "Environment" tag would be listed as a violation. Similar policies can be written for a wide variety of needs (ensuring naming conventions, requiring specific configurations, etc.).

***

By implementing policies as code, you ensure that compliance is proactive and automated. Instead of discovering problems during a security review or after an outage, Firefly helps you enforce your rules continuously.


# Cost Visibility & Optimization

Firefly includes cost management features that bring transparency to cloud spending and help eliminate waste. In many organizations, cloud costs can spiral due to forgotten resources or over-provisioning. Firefly's approach to cost optimization is to first make costs visible at the resource level, and then to highlight and remediate inefficiencies.

## Key features for cost visibility and optimization:

### Resource Provisioning Cost Tracking

Firefly's Workflows can pull in cost data for provisioned resources. You can see how much each resource is costing, often on a monthly basis. For example, in the details of an EC2 instance, Firefly will show an estimated monthly cost. This helps you identify expensive resources quickly and correlate cost with configuration (e.g., high cost might indicate an over-sized instance).

### Cloud Waste Identification

Firefly automatically flags unused or underutilized resources that contribute to cloud waste. Common examples include:

* Unattached volumes (e.g., EBS volumes not attached to any instance, accruing cost with no usage)
* Idle compute instances (VMs running at very low CPU utilization or stopped but still incurring some cost)
* Orphaned IP addresses (allocated IPs not in use)
* Old snapshots or backups beyond retention needs, etc.

In Firefly's Governance page, you can see the list of "Cloud Waste" policies and their estimated cost impact. You can prioritize what to clean up for maximum savings.

### Cloud Waste Remediation

Firefly's AI and rules engine provide recommendations to optimize costs. Firefly can suggest remediation steps for Cloud Waste policy violations. For example, if an EBS volume is found not attached to any instance, Firefly will suggest a command to delete it.

### Enforcing Cost Rules using Guardrails

Using [Firefly Guardrails](/detailed-guides/workflows), you can also set cost-related rules. For instance, you could have a rule that alerts if any development environment exceeds a certain budget, or if someone launches an unusually expensive instance type. Firefly can then act on these Guardrail rules, ensuring that cost controls are part of your deployment process.

### Cost Reports

Firefly provides detailed cost reports, offering breakdowns by Cloud Waste policy. These reports can be exported or shared, proving invaluable for governance meetings, audits, budget tracking, and demonstrating cost optimization progress over time. Learn more about leveraging these insights on the [Analytics Page](broken://pages/A7XDmrhlnqGYO7yegzLM).

***

By acting on such insights (either manually or via Firefly’s automated workflows), you can trim your cloud bills significantly.


# Applications Backup & DR

The Applications Backup & DR feature enables you to back up, monitor the backup process for, and restore your applications and the infrastructure they depend on using an Infrastructure‑as‑Code (IaC)–first approach.

This feature integrates application resilience directly into day‑to‑day cloud operations, enabling teams to define application backup policies, monitor the backup process, and restore applications using Infrastructure as Code (IaC).

## Overview

Applications Backup & DR helps teams:

* Define application‑level backup policies across cloud providers
* Gain clear visibility into snapshots, coverage, and backup health
* Recover predictably by restoring infrastructure as Terraform
* Keep environments consistent under pressure with IaC‑first disaster recovery

This approach ensures consistent, repeatable recovery workflows during incidents.

## Application Policies

Application policies define which applications are backed up and when backups are executed. Applications are identified using tags, which represent logical groupings of cloud resources.

### Creating an Application Policy

To create a new application backup policy:

1. Go to **Applications Backup & DR → Policies**
2. Click **Create Policy**
3. Configure the policy fields:
   * **Policy Name** (required, unique)
   * **Data Source** (AWS, Azure, GCP, OCI etc.)
   * **Region**
   * **Tags** (required key-value pairs that define the application scope)
   * **Schedule Frequency** (On-Demand, Daily, Weekly, Monthly)

Once created, the policy becomes active and generates application snapshots based on the selected schedule.

### Policy Scope and Application Relationships

When a policy targets an application component (for example, an EC2 instance), Firefly automatically captures all required relationships and dependencies needed to restore the application correctly, such as:

* VPC
* Subnet
* IAM instance profile

Resources that are implicitly created as part of these relationships and dependencies are not backed up separately, as they are recreated during restoration.

**The following assets are not eligible for backup:**

* Deleted assets
* Assets in an undetermined state

## Restoring Applications

Applications are restored by generating Terraform code, rather than performing direct cloud mutations.

### Restoring from a Snapshot

To restore resources:

1. Open a snapshot
2. Select one or more resources
3. Click **Restore Selected**
4. Preview the generated Terraform code
5. Continue with Firefly's IaC orchestration flow

This ensures restored resources remain:

* Fully codified
* Auditable
* Aligned with existing IaC standards

## Common Use Cases

* Recover infrastructure after accidental deletion
* Restore a subset of resources without impacting the entire environment
* Recreate infrastructure in a different region using Terraform
* Validate backup coverage and compliance across teams

## Notes & Limitations

* Restoration availability depends on Terraform provider support
* Large snapshots may take longer to load resource inventories

***

Applications Backup & DR provides a safety net for your cloud infrastructure by ensuring you can quickly recover from incidents while maintaining consistency with your Infrastructure as Code practices. By treating disaster recovery as code, teams can test, version, and automate their recovery procedures just like any other infrastructure component.


# AI Assistant

Firefly incorporates an AI Assistant, affectionately called your "Thinkerbell AI," which brings conversational intelligence to cloud management and automation. This feature allows you to interact with your cloud infrastructure using natural language queries and remediate issues with a single click.

## Natural Language Queries

The AI Assistant allows you to ask questions in plain English about your cloud and get instant answers. This is incredibly useful for quick insights or troubleshooting without digging through consoles and dashboards. The AI is context-aware, it knows about your cloud inventory, configurations, and even recent events.\
Check out the [Firefly MCP server](/integrations/mcp) for more details on how to use the AI Assistant in your IDE.

### Example Queries

You can ask questions like:

* "How many EC2 instances do we have running in region us-west-2?"
* "Which IAM users do not have MFA enabled?"
* "Do we have any unmanaged S3 buckets with public access?"

The assistant will parse your question, run the necessary searches or analysis in Firefly, and respond with a concise answer.

## Remediation

The AI Assistant can also suggest remediation steps for different issues detected by Firefly, such as Governance policy violations, Workflows Guardrails violations, etc.


# ChatOps Integration

Integrate Firefly with your team's chat applications to receive notifications and manage cloud resources directly from your communication platforms. This streamlines workflows, improves collaboration, and speeds up incident response.

## How Firefly ChatOps Works

Firefly sends alerts about critical events in your cloud infrastructure directly to your chosen chat tool. These alerts can notify you of:

* **Configuration Drift**: When managed resources deviate from their expected Infrastructure-as-Code state.
* **ClickOps Activity**: Detection of new resources created or existing resources modified manually outside of IaC (e.g., via the cloud console).
* **Policy Violations**: Breaches of your organization's predefined governance, security, or compliance policies.
* **Guardrail Violations**: Issues identified by automated checks during Infrastructure-as-Code deployment workflows, ensuring changes meet your standards before application.
* **Workflow Runs**: Status updates and outcomes of your automated IaC deployment workflows, such as `plan` successes, `apply` failures.

## Key Benefits

Integrating Firefly with your chat applications provides several key benefits:

* **Immediate Visibility & Context**: Receive real-time alerts for critical infrastructure events. Notifications include direct access to resource details and deployment information, providing instant context for quick assessment and informed action.
* **Streamlined Collaboration**: Discuss, diagnose, and resolve infrastructure issues directly within your team's existing chat channels, fostering faster response times and collaborative problem-solving.
* **Focused Alerts**: Customize notification settings to control which events trigger alerts and their destinations. This reduces noise and ensures your team can concentrate on the most critical information.


# Account Setup & Onboarding

To start using Firefly, sign up for an account on the [Firefly platform](https://app.firefly.ai). Once logged in, Firefly will guide you through an Onboarding Wizard. In this wizard, you will connect your data sources and tools so Firefly can scan your cloud environment.

The wizard prompts you to integrate:

1. **Cloud providers and SaaS** – your cloud accounts (AWS, Azure, Google Cloud, Kubernetes, etc.) or services like Datadog, so Firefly can inventory your assets. Learn more about [data source integrations](/integrations/data-sources).
2. **Workflows** – to integrate with your existing CI/CD pipelines, so Firefly can scan your Terraform and OpenTofu deployments and enforce guardrails. Learn more about [Workflows integration](/integrations/workflows).
3. **Version control** – linking your Git repositories (GitHub, GitLab, Bitbucket, etc.) so Firefly can map resources to code and even open pull requests for changes. Learn more about [VCS integrations](/integrations/version-control).
4. **Notification channels (ChatOps)** – such as Slack or Microsoft Teams, to send notifications. Learn more about [ChatOps integrations](/integrations/notifications).

Follow the on-screen steps in each section of the wizard to provide the necessary credentials or permissions for each integration. Once you've added all the integrations you want, click "Take me in" to complete onboarding.


# Connecting Additional Integrations

After onboarding, you can add or manage integrations at any time via **Settings > Integrations** in the Firefly platform. To add a new integration, go to the Integrations page, click **"Add New"**, and select the type of tool or service you wish to connect from the categorized options.

Firefly supports several categories of integrations, allowing you to expand its capabilities and tailor it to your specific operational needs.

## Types of Integrations You Can Add

You can connect various tools and services to Firefly to enhance its functionality. These fall into the following categories:

### Data Sources (Cloud Providers & SaaS)

* **Purpose:** To allow Firefly to scan and inventory your assets from cloud environments (like AWS, Azure, Google Cloud, Kubernetes) and other SaaS services (e.g., Datadog, Okta). This enables comprehensive visibility into your cloud footprint.
* **General Process:** Involves granting Firefly read-only access via secure mechanisms like IAM roles, service accounts, or API keys, following guided setup wizards within Firefly.
* **Learn more:** See the [Data Source Integrations section](/integrations/data-sources) for detailed guides.

### Workflows (CI/CD Pipelines)

* **Purpose:** To integrate Firefly into your existing CI/CD pipelines (e.g., Jenkins, GitLab CI, GitHub Actions). This allows Firefly to scan Infrastructure-as-Code (IaC) deployments (like Terraform, OpenTofu) and enforce predefined guardrails before changes are applied.
* **General Process:** Involves adding Firefly analysis steps to your pipeline definitions.
* **Learn more:** Refer to the [Workflows Integration documentation](/integrations/workflows).

### Version Control Systems (VCS)

* **Purpose:** To link your Git repositories (e.g., GitHub, GitLab, Bitbucket) with Firefly. This enables Firefly to map cloud resources back to their IaC definitions, understand code context, and potentially open pull requests for automated IaC generation or remediation.
* **General Process:** Requires authorizing Firefly to access your repositories, via dedicated application or personal access tokens with appropriate permissions.
* **Learn more:** Find details in the [VCS Integrations section](/integrations/version-control).

### Notification Channels (ChatOps)

* **Purpose:** To send real-time alerts and notifications about important events detected by Firefly (such as configuration drift, policy violations, or new unmanaged resources) directly to your team's communication platforms.
* **General Process:** Involves configuring connections to services like Slack, Microsoft Teams, PagerDuty, or email. This includes setting up webhooks or authorizing Firefly applications within your chosen chat or alerting tools.
* **Learn more:** Consult the [ChatOps Integrations guide](/integrations/notifications).

### Project Management Tools

* **Purpose:** To integrate Firefly with your project management tools (e.g., Jira). This allows you to on-demand create tickets for cloud issues.
* **General Process:** Requires creating a token and configuring the integration in Firefly.
* **Learn more:** Refer to the [Project Management Tools Integration documentation](/integrations/project-management).

### IaC Remote Backends

* **Purpose:** To integrate Firefly with your IaC remote backends (e.g., Terraform Cloud, Terraform Enterprise). This allows Firefly to scan your IaC state files.
* **General Process:** Requires creating a token and configuring the integration in Firefly.
* **Learn more:** Refer to the [IaC Remote Backends Integration documentation](/integrations/iac-remote-state).

## General Steps to Add an Integration

Regardless of the integration type, the process generally follows these steps within the Firefly UI:

1. Navigate to **Settings > Integrations**.
2. Click the **"Add New"** button. This will present a list or categorized view of available integrations.
3. Select the specific cloud provider, service, or tool you wish to integrate.
4. Follow the on-screen instructions and guided procedures provided by Firefly. Each integration will have a specific set of steps, which may involve providing credentials, authorizing access, or configuring endpoints. Firefly's documentation provides detailed walkthroughs for each supported integration.

Once an integration is successfully configured, Firefly will begin to utilize it according to its purpose. For example:

* **Data Sources:** Firefly will start scanning for assets and ingesting metadata.
* **Workflows:** Firefly will be ready to analyze pipeline runs.
* **VCS:** Firefly will link code to resources and enable IaC-related features.
* **Notification Channels:** Firefly will be able to send alerts to the configured channels.
* **Project Management Tools:** Firefly will be able to create tickets for cloud issues.
* **IaC Remote Backends:** Firefly will be able to scan your IaC state files.

You can manage (edit, disable, or delete) existing integrations from the same **Settings > Integrations** page.


# UI Walkthrough & Navigation

After completing onboarding and adding integrations, you'll land on the Firefly Dashboard. The Firefly web interface is organized with a left-hand navigation menu and main content area. Major sections in the navigation include:

* **Dashboard** - High-level overview of your cloud environment. Learn more about [Dashboard](/detailed-guides/dashboard-overview).
* **Inventory** - Complete list of all discovered cloud assets. Learn more about [Inventory](/detailed-guides/cloud-asset-inventory).
* **IaC Explorer** - View and navigate your Infrastructure-as-Code stack files, and code. Learn more about [IaC Explorer](/detailed-guides/iac-explorer).
* **Workflows** - Review your pipelines and set up guardrails to enforce compliance. Learn more about [Workflows](/detailed-guides/workflows).
* **Governance** - Define and review compliance policies. Learn more about [Governance](/detailed-guides/policy-and-governance).
* **Analytics** - Review your analytics and insights. Learn more about [Analytics](https://github.com/gofireflyio/product-docs/blob/main/getting-started/broken-reference/README.md).
* **Notifications** - Review your notifications and preferences. Learn more about [Notifications](broken://pages/fK1QFjrKh9Y4YrQvivAl).
* **Settings** - Manage integrations, users and configuration options.

Spend a minute to familiarize yourself with the navigation menu and what each section offers. For instance, under Settings you'll find:

* IaC-Ignored rules setup. Learn more about [IaC-Ignored rules](/detailed-guides/cloud-asset-inventory/creating-iac-ignore-rules).
* Drift exclusion rules setup. Learn more about [Drift exclusion rules](/detailed-guides/cloud-asset-inventory/creating-exclude-drift-rules).
* Integrations management (to add/remove cloud accounts). Learn more about [Integrations](/integrations/overview).
* Access Management. Learn more about [Access Management & RBAC](/getting-started/access-management-rbac).


# First Steps in Firefly

A few initial activities are recommended to get value from Firefly:

## Explore the Cloud Inventory

Navigate to the Inventory page to see the list of all assets Firefly has aggregated from your connected accounts. Here you can filter and search resources across AWS, Google Cloud, Azure, Kubernetes, and SaaS providers all in one place.

Try using the filters at the left sidebar of the Inventory to drill down by data source, region, resource type, tag, or owner. For example, you might filter to a specific AWS account and resource type EC2 Instance to see your VMs, or filter by an Owner tag to see assets owned by a team.

The Inventory is your single source of truth for what's running in your cloud. Click on a resource in the table to view its Asset Details – including its configuration info, tags, IaC state (if managed by code), mutations (change history), and any policy violations or drift status.

This will help you quickly identify which assets are "codified" (managed by IaC) and which are "unmanaged" (created manually and not yet in code). Firefly automatically classifies every resource as codified, drifted, unmanaged, or ghost.

As a best practice, note any important unmanaged assets – you can decide to codify them (generate IaC) to bring them under control.

## Set Up a Policy (Governance)

Go to the Governance page to view built-in policy checks and optionally create your first custom policy. Firefly comes with a library of built-in policies (powered by OPA's Rego rules) that check your assets for security, compliance, and best practices issues.

These include categories like access control, encryption, tagging, cost optimization, etc. Initially, you will see a summary of how many resources pass or violate the built-in policies.

As a new user, a good first step is to identify one or two critical policies to enforce. For example, you might want to ensure "No public S3 buckets" or "Databases must be encrypted". You can create a Custom Policy for this if it isn't covered by the built-ins.

To create a policy:

1. Click "+ Custom Policy".
2. Give it a name.
3. Choose a category (or create a new one) and severity level.
4. Select the scope of the policy (e.g. all resources, or only specific resources and/or accounts).
5. Write the rule in Rego (or use the AI policy generator to help).

Firefly provides an Input Schema and testing interface so you can validate the policy against existing assets before saving. Once your policy is active, Firefly will scan all relevant assets and report any violations.

The Governance page dashboard will show a compliance score (the percentage of assets passing each policy). As you get started, setting up a few key policies establishes enforcement for your environment.

## Configure Notifications

It's important to get alerts when Firefly detects changes or issues. Under **Settings > Notifications**, configure how you'd like to receive alerts about drift, policy violations, or other events.

Firefly can send notifications to various channels: you can integrate Slack, Microsoft Teams, PagerDuty, email, or create Jira tickets, among others.

For example, for Slack, you have two options:

* Using the Firefly Slack App.
* Setting up a webhook URL.

In either case, you'll authorize Firefly to post messages to your workspace. Similar steps apply for Teams (via an incoming webhook connector) and PagerDuty (via an API integration key).

After integration, define what events trigger notifications. For example, you might enable alerts for:

* Drift detected (when an infrastructure change occurs outside of IaC).
* Policy violation detected.
* New ClickOps event detected.

Firefly will then send a message with details whenever those events occur. According to your configuration, Firefly will deliver messages to your chosen channel – e.g. posting a Slack message when a non-compliant change is blocked or sending a PagerDuty incident when a drift is detected.

Setting up notifications early ensures you have near real-time visibility. Firefly's platform is event-driven for AWS, Azure, and Google Cloud, tracking CloudTrail and equivalent events in near real-time, so you will be promptly alerted of changes.

As a next step, you can also explore the Event Center to see a log of all changes detected. Notifications and event monitoring help your team respond quickly to any issues that Firefly surfaces.

## Configure Workflows and Guardrails

Firefly Workflows automate your Terraform and OpenTofu deployments. You can either integrate your existing CI/CD pipeline or use Firefly-managed workflows where Firefly handles the execution.

### Integrating Existing CI/CD Pipelines

If you have an established CI/CD process, you can integrate it with Firefly using the `fireflyci` tool. This provides enhanced visibility and monitoring within Firefly without overhauling your setup. For more details, see [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows).

### Creating Firefly-Managed Workflows

Alternatively, let Firefly manage your IaC pipeline execution. For more details, see [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows).

### Creating Self-Hosted Managed Workflows

Another option is to deploy self-hosted runners within your own infrastructure to execute IaC operations while maintaining full control over network access, data residency, and compliance requirements. For more details, see [Creating a Self-Hosted Runner Pool](/detailed-guides/workflows/creating-self-hosted-runner).

### Implement Guardrail Rules

Guardrails enforce policies (cost, security, tagging, resource) on your IaC deployments, blocking non-compliant changes.

1. Go to **Workflows > Guardrails** and click "+ Add New".
2. Choose Rule Type: Cost, Policy (listed in the Governance page), Resource, or Tag.
3. Name Your Rule and define its Violation Behavior (Strict Block or Flexible Block with overrides).
4. Define Scope: Specify which Workspaces, Repositories, Branches, or Labels the rule applies to.
5. Set Rule-Specific Criteria: For example, for a Cost rule, set a budget change threshold. For a Policy rule, select policies.
6. Optionally, Configure Notifications for violations or overrides. For more details, see [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules).

By setting up workflows and guardrails, you gain automated, policy-driven control over your IaC deployments.

***

By completing these first steps – connecting your accounts, exploring the inventory, defining basic policies, enabling notifications, and configuring workflows with guardrails – you'll have a solid foundation in Firefly. You'll be able to continuously monitor your cloud assets, get alerted to important changes, manage your IaC deployments with policy enforcement, and start improving your infrastructure management with Infrastructure-as-Code.


# Access Management (RBAC)

Firefly’s Access Management lets you control who can access specific parts of your cloud environment, which actions they can perform, and which data sources their permissions apply to.

This provides stronger security, clearer governance, and flexibility as your teams scale.

## Overview

Access Management introduces a role-based permission model across the Firefly platform.

With RBAC you can:

* Assign fine-grained permissions for every part of the platform
* Control access by Users, Teams, and Service Accounts
* Generate API keys with scoped permissions
* Limit access to specific cloud integrations or allow full-tenant access
* Enforce least-privilege access across your organization

RBAC applies to all major Firefly areas, including Inventory, Governance, Integrations, Notifications, IaC Explorer, and more.

***

## Access Management Menu

Access Management consolidates identity and access controls into one place:

**Access Management →**

* Users
* Teams
* Service Accounts
* Roles
* API Keys (per Users, Teams, Service Accounts)

***

## Key Concepts

### Roles

A role defines a set of permissions.

Roles can be assigned to:

* Users
* Teams
* Service Accounts

#### Default roles

Every tenant includes two built-in roles:

* **Admin** – Full access to all scopes and actions.
* **Viewer** – Read-only access to all supported areas.

Admins can create additional custom roles.

***

### Permission modes

When creating or editing a role, each role can operate in one of three modes:

#### Full Access (Admin)

Grants all available permissions across all data sources.\
All actions are enabled, and all integrations are accessible.

#### Read-only

Users can view everything but cannot create, update, delete, or remediate.

#### Limited Access (Scoped)

Fully customizable, including:

* Specific integrations (for example, specific AWS/GCP/Azure accounts)
* Specific actions (for example, “View Inventory” but not “Delete Asset”)

This is ideal for least-privilege or team-specific access.

***

### Service accounts

Service accounts let you create identities for automation tools or CI/CD systems without tying them to human users.

Each service account can have:

* Roles
* API keys

***

## Migration from legacy permissions

Firefly automatically migrates existing tenants into the new RBAC model.

### What happens during migration

* Existing Admins become **Admin** role users.
* Existing Viewers become **Viewer** role users.
* Legacy tenant-level API keys are migrated into **Service-Account-level API keys**.
* All migrated keys retain their original capabilities.

***

## Best practices

* Use **Teams** to manage access at scale.
* Use **Service Accounts** for automation instead of human API keys.
* Start with **Read-only** roles for new users.
* Use **Scoped roles** for vendors, temporary users, or least-privilege access.
* Rotate API keys regularly, especially after migration.
* Review role assignments periodically (for example, quarterly).

***

## Limitations

* Only **Admins** can access the **Access Management** screen.
* Only **Admins** can manage **Integrations**, including create, update, and delete operations.
* Legacy **API keys** will be migrated and linked to a specified **Service-Account**.
* Workflows permissions will be supported using Access Management in the next phase.


# Dashboard Overview

The Dashboard is the home page of Firefly and provides a bird's-eye view of the health and state of your cloud environment. It aggregates key metrics across all integrated providers to highlight areas that may need attention. When you open the Dashboard, you'll see summary widgets/cards organized into the following key areas:

## Cloud & SaaS Accounts Summary

A breakdown of cloud and SaaS accounts by Data Source (cloud provider or service). This widget shows how your cloud and SaaS accounts are distributed across AWS, Google Cloud, Azure, Kubernetes, and any SaaS integrations, along with the third-party detection tools installed on those clouds. Each provider icon displays a count of connected accounts and their associated monitoring tools (such as Datadog, New Relic, Grafana, etc.). It helps answer "what cloud and SaaS accounts do we have and what monitoring is in place?" at a glance.

The summary includes:

* **Total integrated accounts** across all cloud and SaaS providers.
* **Third-party detection tools** installed and configured on each cloud and SaaS account.
* **Provider distribution** showing the breakdown of accounts by cloud and SaaS provider.

## IaC Management

This section provides insights into your Infrastructure as Code adoption and automation workflows:

* **IaC Stacks**: Number of IaC stacks detected and tracked by Firefly (e.g., "120 Terraform state files").
* **Workflow Execution**: Number of workflow runs executed in the past week, showing automation activity and IaC deployment frequency.
* **State File Health**: Overview of the health and status of your IaC stacks.

For instance, it might show "IaC Stacks: 120 Terraform state files" and "Workflows: 45 executions this week", indicating how large your IaC footprint is and how active your automation processes are.

## Cloud Asset Management

This comprehensive section covers your cloud asset inventory, coverage, and drift management:

### IaC Coverage & Asset Posture

A summary of what percentage of your resources are codified vs. how many are drifted or unmanaged:

* **Codified assets**: Those already managed by IaC.
* **Drifted assets**: Those where the live configuration has deviated from the code.
* **Unmanaged assets**: Not managed by any IaC (created manually).

For example, the dashboard might show "80% codified, 11% drifted, 9% unmanaged," giving you instant insight into IaC adoption.

### Asset Distribution & Discovery

* **Total Assets**: Key count of all assets discovered across your cloud environment (e.g., "Assets: 5,230").
* **Global Asset Map**: Interactive world map showing the geographical distribution of your cloud resources across regions and availability zones.

> **Note:** Total assets count represents the sum of all assets excluding the assets created by Firefly integration.

### Drift & Change Detection

* **Clickops Events**: Real-time detection of manual changes made manually in the cloud environment.
* **Drift Cost Impact**: Yearly financial impact of configuration drift, showing potential cost implications of the drifted assets.
* **Top 5 Drifted Properties**: Specific settings that are most commonly drifting, like security group rules, IAM policy changes, or resource configurations.
* **Top 5 Unmanaged Cloud Resources**: Priority list of unmanaged assets that should be brought under IaC control, helping you focus codification efforts.

## Cloud Governance

This section focuses on compliance, optimization, and governance across your cloud environment:

### Cloud Waste & EOL Detection

* **Cloud Waste Detected**: Summary of the cloud waste detected in the environment with estimated yearly savings if cleaned up.
* **EOL & Service Lifecycle**: Number of assets using end-of-life or deprecated services, helping maintain security and compliance.

### Compliance & Tagging

* **Tagging Coverage**: Percentage of resources with proper tags applied, showing governance maturity.
* **Compliance Packs**: Average compliance posture across different compliance frameworks (SOC 2, PCI DSS, GDPR, etc.).

## Using the Dashboard Effectively

Overall, the Dashboard is meant to quickly answer "Is everything OK in my cloud right now? What should I focus on first?". For example, a high drift count suggests you check drifts, or a large number of unmanaged assets suggests using codification to bring them under IaC control.

Use the Dashboard daily to monitor trends. If you see the codified percentage going up over time and drift going down, that's a positive sign your IaC adoption is improving. Conversely, a spike in cloud waste or EOL assets would prompt immediate investigation.

Each widget on the Dashboard is interactive. Clicking on a section will deep-link you to the relevant detailed page (Inventory, Governance, etc.) for further action.


# Cloud Asset Inventory

The Cloud Asset Inventory page is the heart of Firefly, providing a comprehensive, searchable list of all your cloud resources across accounts and regions. This page enables managing resources, filtering, and exporting your inventory data in powerful ways.

When you navigate to **Inventory**, you'll see a table of assets. Each row is a resource (e.g. an EC2 instance, an S3 bucket, a GKE cluster, a Datadog monitor) along with key properties: cloud provider, asset type, name, environment/tag, IaC status, etc. At the top, and on the left side of the table, there are multiple ways to filter and segment the data:

## Filter by Provider, Type, Tags, and more

The Inventory includes a filter menu with dropdowns for Data Source (provider account), Asset Type, Location (region/cluster), Tags, Owner, and so on. For example, you can select Data Source = `AWS Account A` and Asset Type = `S3 Bucket` to list only S3 buckets in that account.

The Owner filter is especially useful to see who made the last change: for AWS resources, Firefly can show the CloudTrail Event Owner and event time, for IaC-managed resources, it shows the Git commit author and commit date (when Git integration is enabled). You can combine filters (e.g. all AWS EC2 instances in us-east-1 tagged with `Environment:Production`). The table updates in real-time as you apply filters.

## Asset Categories (Live vs Deleted)

Just above the table, there are quick toggles for viewing Live assets or Deleted assets. Firefly keeps track of assets that existed and were later terminated. By toggling **Deleted**, you can see resources that have been removed (this helps with auditing what was deleted). Usually you'll keep it on Live to see active resources. There is also a **Types** view that groups assets by category (e.g. all EC2 instances, all S3 buckets) for a high-level look.

## Asset Flags

In the top-right corner of the Inventory, you'll find flag filters to highlight certain conditions. These include flags such as Policy (showing assets with policy violations), Mutations (assets with changes/revisions you can compare), Favorites (assets you've starred/bookmarked), Git (assets whose IaC code is linked to Git and can be traced), GitOps (assets managed by GitOps tools like Argo CD), and Relationships (assets that have dependency mappings).

For example, clicking the Policy flag will filter the list to only assets that have one or more governance policy violations (letting you focus on non-compliant resources). These flags are a quick way to slice the inventory by specific governance or metadata criteria.

## Search Bar

You can also perform a free-text search across all assets using the search bar. This does a full-text search on resource names and configurations. For instance, you could search for an IP address like `0.0.0.0/0` to find any security group or firewall rule allowing open access. Or search a specific resource ID or name to jump directly to it. This is very handy when you have thousands of assets, just type a keyword and Firefly will filter the inventory to matching items.

Once you have a filtered view, you can save custom views for reuse. From the **Views** menu at the top bar, select **Save Current View** to bookmark your filter set (e.g. a view for *Prod Kubernetes Clusters*). This allows quick access later without reapplying filters.

## Asset Details

Clicking on a specific asset row opens the Asset Details pop-up. Here you can manage the individual resource and see rich information across several tabs: **Information**, **Configuration**, **Mutation Log**, **Event Viewer**, **Favorites**, **Relationships**, and **Architecture Diagram**.

### Information Tab

Basic info about the asset, its cloud metadata, tags, creation date, etc. If the asset is managed by IaC, it shows which stack and file it comes from. If it's unmanaged, you will see an option to codify it. There's also a Governance sub-tab showing any policy violations affecting this asset (e.g. *Encryption not enabled* with severity level). If the asset's Terraform code is in an integrated Git repo, a Git sub-tab shows a direct link to the code and the last commit info.

### Configuration Tab

This shows the actual configuration associated with the asset. It will show the resource configuration retrieved from the cloud provider. If that asset is drifted, there is a **Drift Details** button at the bottom left of the pop-up that you can click to see changes side by side.

### Mutation Log

Firefly tracks changes (mutations) to each asset over time. In the Mutation Log tab, you can see a timeline of changes detected. If an asset's configuration changed (via IaC or manually), each change is listed with timestamp and what changed. This is great for audit trail and understanding drift. Firefly even allows rollback: if you select a previous revision in the Mutation Log, you can click **Codify Revision** to generate the code to revert the asset back to that state.

### Event Viewer

For cloud assets, Firefly can show the audit log events (like AWS CloudTrail events or Google Cloud Audit Logs) related to the asset. In the Event Viewer tab, you will see a graph of recent operations on this resource and a list of events (e.g. an API call that modified a security group). You can expand an event to see details of the request and response. This helps pinpoint who or what changed an asset, which is useful for security and compliance investigations.

### Favorites Tab

Favorites is Firefly's bookmarking feature for the inventory. Use it to star a resource so you can flag useful assets or good examples and find them again quickly. Favorited assets are marked with a star on their inventory row, and you can narrow the inventory to just your favorites using the **Favorites** flag at the top of the page. Favorited resources can also be included when you export the inventory to CSV.

### Relationships & Architecture Diagram

The **Relationships** tab provides a visual map of how the asset connects to others. For example, if the asset is a VM, it will show relationships to the VPC, subnets, security groups, etc. You can click on any related resource in the map to navigate to its details. In the **Architecture Diagram** tab, Firefly can generate an architecture diagram for managed assets, illustrating its dependencies in the IaC stack. This is extremely helpful to understand context (e.g. this database is part of a cluster, or this Kubernetes Deployment owns these Pods).

## Asset Actions

At the bottom of the Asset Details pop-up, you will find action buttons to manage the resource:

* **Codify** – generate IaC code for the asset.
* **Migrate** – for cloud resources, Firefly offers a Migrate feature to convert the resource into another cloud provider (e.g. generate Terraform for an EC2 instance on Azure). This is advanced and used for cross-cloud migration scenarios.
* **Share** – copy a direct link to this asset (to share with a teammate or in an incident ticket). This is useful for sharing the asset details with a teammate or in an incident ticket.
* **Delete** – remove the asset. For unmanaged assets, Firefly will provide a delete command. For codified assets, Firefly will open a pull request to delete its IaC definition (useful if you want to decommission it from code).
* **Create Jira Issue** – if integrated, a button to create a Jira issue pre-filled with this asset's info (for tracking a problem or task related to the asset). This is useful for tracking a problem or task related to the asset.
* **Jump to Code** – if the asset is managed by code in Git, this will open your Git repository directly at the code file and line for this resource.
* **Jump to Console** – opens the cloud provider's console/web UI for the resource (e.g. AWS Console page for that EC2 instance).

## Bulk Actions

Using the Inventory page, you can perform bulk actions as well. For example, you can select multiple unmanaged assets (checkboxes in the table) and choose *Codify* to generate IaC for all of them in one go. Firefly will ask you which IaC format (Terraform, Pulumi, etc.) and then produce code for each selected resource. Likewise, you can select any resources and hit the trash icon to delete them.

## Exporting Inventory Data

One powerful feature is Exporting the inventory. If you want to generate a report of assets, click the Export option (at top-right of the table). You can export the filtered results in CSV or JSON format. Firefly allows exporting up to 10,000 assets based on your current filters. For example, you could filter to *unmanaged assets in AWS* and export that list as a CSV to share with your team. The export will include the columns visible in the inventory (like resource name, type, cloud, tags, etc.). This is useful for offline analysis, compliance audits, or integration with other tools.

## Summary

In summary, the Cloud Asset Inventory is where you view and manage all resources. Use filtering to narrow down, use the asset details to investigate and take action (codify or remediate drifts), and export or save views as needed. It's a good practice to regularly review the Inventory for any anomalies: e.g., check the *Unmanaged* filter to see if new resources popped up outside of code, or use the *Policy* flag to see non-compliant assets and address them. The Inventory keeps your cloud estate transparent and under control by centralizing all asset information in one place.

## Related Guides

For more detailed information on specific cloud asset inventory tasks, see these guides:

* [**Creating Exclude-Drift Rules**](/detailed-guides/cloud-asset-inventory/creating-exclude-drift-rules) - Learn how to create rules that tell Firefly to ignore specific drift issues so it stops alerting about those particular differences.
* [**Creating IaC-Ignore Rules**](/detailed-guides/cloud-asset-inventory/creating-iac-ignore-rules) - Learn how to create rules that exclude specific unmanaged assets from IaC coverage calculations and recommendations.
* [**Deleting Assets**](/detailed-guides/cloud-asset-inventory/deleting-assets) - Learn how to safely delete both unmanaged (cloud-only) assets and codified (managed by IaC) assets from your environment.
* [**Remediating Drifts**](/detailed-guides/cloud-asset-inventory/remediating-drifts) - Learn how to remediate drifted assets by either aligning your IaC code to match the current asset configuration or reconciling assets to match your IaC code.


# Remediating Drifts

Drifted assets are resources whose configuration in your cloud environment differs from the configuration defined in your Infrastructure as Code (IaC) stack. Remediating drift ensures your cloud stays in its optimal, intended state.

This guide explains how to remediate drifted assets in Firefly, either by aligning your IaC code to match the current asset configuration or by reconciling the asset to match the desired configuration in your IaC.

> **Note:** Fixing drifts promptly helps maintain security, compliance, and operational consistency.

## Before you begin

Verify your Version Control System (VCS) is integrated with Firefly (e.g., GitHub, GitLab).

## Procedure

1. **Go to Drifted Assets**: In the Firefly console, navigate to **Inventory** and filter to view the *Drifted* assets. This page lists all assets detected as drifted.
2. **View Drift Details**: Click on the asset row to open the asset details pop-up. In the pop-up, click on the **Drift Details** button. A window appears, displaying the difference between the Running Configuration (cloud value) and the Desired Configuration (IaC state value).
3. **Review the Drift Remediation Options**: In the Drift Details window, you will see two options to remediate the drift:
   * **Align the IaC to the Asset (Update Code)**: This option will update your IaC code to match the current configuration of the asset in the cloud.
   * **Reconcile the Asset to the IaC (Update Cloud)**: This option will update the asset in the cloud to match the desired configuration in your IaC code.

### Option 1: Align the IaC to the Asset (Update Code)

If you want to update your IaC code to match the current configuration of the asset in the cloud:

1. In the Drift Details window, review the code block change suggested by Firefly.
2. Click **Create Pull Request**. Firefly will generate a code change in your IaC repository to align the code with the asset's current configuration.
3. Review and merge the pull request in your VCS to update your IaC code.
4. (Optional) To refresh the Terraform state, copy and run the provided `terraform apply -refresh-only` command in the CLI where your Terraform workspace is configured. This will update the Terraform state to reflect the current configuration of the asset in the cloud.

```bash
# Example: Refresh Terraform state to synchronize with the cloud
terraform apply -refresh-only -target <resource-address>  # Replace <resource-address> with the actual resource
```

### Option 2: Reconcile the Asset to the IaC (Update Cloud)

If you want to update the asset in the cloud to match the desired configuration in your IaC code:

1. In the Drift Details window, copy the suggested `terraform apply` command.
2. Run the command in the CLI where your Terraform workspace is configured. This will update the asset in the cloud to match your IaC definition.

```bash
# Example: Apply Terraform changes to fix drift in the cloud
terraform apply -target <resource-address>  # Replace <resource-address> with the actual resource
```

> **Tip:** Always review the proposed changes before applying them to production environments.

## Summary

* Drifted assets are resources whose configuration differs between the cloud and your IaC code.
* You can remediate drift by either aligning your IaC code to the asset's current state or by reconciling the asset to match your IaC code.
* Use Firefly's Drift Details and Remediate Drift features to generate code changes or CLI commands for remediation.
* Always review and test changes before applying them in production.


# Deleting Assets

Deleting assets in Firefly removes them from your cloud environment or from your Infrastructure as Code (IaC) repository, depending on how the asset is managed. This guide explains how to safely delete both unmanaged (cloud-only) assets and codified (managed by IaC) assets, including drifted and ghost resources.

> **WARNING:** Deleting assets is a destructive action. When you delete an asset using the CLI commands provided by Firefly, the resource is permanently removed from your cloud provider. Always double-check your selection before proceeding.

## Deleting Unmanaged Assets

Unmanaged assets are resources that exist in your cloud environment but are not managed by your IaC code. To delete these assets:

1. **Go to Inventory**: In the Firefly console, navigate to the Inventory page. This lists all discovered assets, including unmanaged ones.
2. **Select the asset(s) to delete**: Find and select the unmanaged asset(s) you want to remove. Unmanaged assets are marked as such in the inventory list.
3. **Click the trash icon**: With the asset(s) selected, click the trash (delete) icon. Firefly will generate the appropriate CLI command(s) for your cloud provider to delete the resource(s).
4. **Copy and run the CLI command(s)**: Copy the provided CLI command(s) and run them in your cloud provider's command line interface (e.g., AWS CLI, Azure CLI, Google Cloud CLI). This action will delete the asset(s) from your cloud environment.

```bash
# Example: Deleting an AWS S3 bucket using AWS CLI
aws s3 rb s3://your-bucket-name --force  # This command deletes the specified S3 bucket and all its contents
```

> **Note:** The exact CLI command will depend on the asset type and cloud provider. Always review the command before executing it.

## Deleting Codified, Drifted, or Ghost Assets (via IaC)

Codified assets are managed by your IaC code (such as Terraform). Drifted assets have diverged from their IaC definition, and ghost assets are resources that exist in code but not in the cloud. To delete these types of assets, you must update your IaC repository.

### Before you begin

Ensure the IaC file for the asset you want to remove is present in the Version Control System (VCS) integrated with Firefly (e.g., GitHub, GitLab).

### Procedure

1. **Go to Inventory**: In the Firefly console, navigate to the Inventory page.
2. **Select the asset(s) and click the trash icon**: Find the codified, drifted, or ghost asset(s) you want to delete. Select them and click the trash (delete) icon.
3. **Choose how to update the code**:
   * To remove the asset from code, leave the **Comment out code** toggle off. Firefly will generate a code change that deletes the resource block from your IaC file.
   * To make the asset inactive without deleting the code, switch the **Comment out code** toggle on. This will comment out the resource block, making it inactive but still present in the file.
4. **Create a Pull Request**: Click **Create Pull Request** to propose the code change in your VCS. This allows your team to review and approve the deletion.
5. **Merge the Pull Request**: After approval, merge the pull request into your main branch. This updates your IaC repository to reflect the asset removal.
6. **Apply the change in your cloud environment**:
   * Run `terraform apply` to update your cloud environment and remove the asset.
   * Alternatively, run `terraform destroy` if you want to remove all resources defined in the IaC file.

```bash
# Example: Remove a resource using Terraform
terraform apply  # Applies the code change and deletes the asset from the cloud

# Example: Destroy all resources in the current Terraform configuration
terraform destroy  # Use with caution; this deletes all managed resources
```

> **Tip:** Commenting out code is useful if you want to temporarily disable a resource without deleting its configuration. Removing the code entirely is best for permanent deletions.

## Summary

* Use the CLI command for unmanaged assets to delete them directly from the cloud.
* For codified, drifted, or ghost assets, update your IaC code and apply the changes to remove the asset from both code and the cloud.
* Always review destructive actions and code changes before applying them to production environments.


# Creating IaC-Ignore Rules

An IaC-Ignore rule allows you to tell Firefly to ignore specific unmanaged assets in your cloud inventory from being counted in IaC tracking. In other words, if there are cloud resources not managed by Infrastructure-as-Code that you want to exclude from Firefly's IaC coverage calculations, you can create a custom ignore rule to omit them. Once an asset matches an IaC-Ignore rule, it will be marked *IaC-Ignored* and no longer considered in your IaC coverage or recommendations.

## How to add an IaC-Ignore rule:

1. **Open IaC-Ignored settings**: In the Firefly app, go to **Settings > IaC-Ignored**. This section allows you to manage ignore rules for unmanaged assets.
2. **Add a new rule**: Click on **+ Add ignore rule**. This will start the wizard to create a custom ignore policy.
3. **Name and describe the rule**: Give the rule a clear Name and an optional Description so you and your team know what its purpose is. For example, *Ignore default VPCs* could be a rule name.
4. **(Optional) Label the rule**: You can assign a label or category to the rule (or create a new label) to help organize multiple ignore rules. This is useful if you have many rules and want to filter or group them.
5. **Choose the scope**: Click Next, then select the scope of the ignore rule. The scope determines which assets the rule will target. You can select specific resource types. For example, you might scope the rule to ignore only in scope of EC2 instances.
6. **Define the ignore logic**: In the provided code editor, write the rule logic using the Rego policy language (the language used by Open Policy Agent). Firefly uses Rego to define custom rules. For instance, you could write a Rego expression that matches resources by certain tags, names, or types that you consider should be ignored.

   **Example Rule - Ignoring Default Resources:**

   ```rego
   firefly {
       exclude
   }

   exclude {
       input.id = "default"
   }
   ```

   This example rule will ignore any asset where the `id` field equals `default`. This is particularly useful for ignoring default resources that cloud providers automatically create (like default VPCs, default security groups, etc.). The rule works by:

   * The `firefly` rule evaluates to true when the `exclude` rule is satisfied.
   * The `exclude` rule matches any asset where `input.id` equals `default`.
   * When both conditions are met, Firefly will mark the asset as IaC-Ignored.
7. **Evaluate matched assets**: Before finalizing, you can preview which assets would be ignored by this rule. Use the **Evaluate** button to see a list of assets that currently meet the rule criteria and would become IaC-Ignored. This helps validate that your rule is correctly targeting the intended assets.
8. **Save the rule**: Click Next and then Done to create the ignore rule. The rule will be activated, and any asset matching the rule's conditions will now show up as IaC-Ignored in the inventory.

After creating an ignore rule, those assets will be excluded from IaC coverage metrics. You can view all ignored assets by going to the Inventory and using the filter *IaC-Ignored* on the created rule(this filter will show assets that have been marked to ignore). If needed, you can always disable or delete the custom rule later via the **Settings > IaC-Ignored** page (there is a toggle to turn rules on/off, or an option to remove the rule entirely).

## When to ignore unmanaged assets:

Creating IaC-Ignore rules is helpful in several scenarios:

* **Default cloud resources**: Cloud providers often create default resources (like a "default VPC" or default subnets in a new AWS account). These are unmanaged (not created by your IaC), but you might not want them counted as gaps in your IaC coverage. Marking them as IaC-Ignored will exclude such defaults from your IaC statistics. Firefly comes with built-in rules for some of these cases.
* **Benign unmanaged assets**: If certain resources are intentionally left out of code (perhaps managed manually or by another system), and you don't plan to codify them, ignoring them can reduce noise. For example, maybe an experimental server or a one-off cloud service that is not worth codifying – you can ignore it so Firefly doesn't flag it as *unmanaged* in your reports.
* **Ephemeral/test resources**: Some teams create temporary resources for testing or development that are short-lived. If Firefly detects these as unmanaged, it might not be useful to track them. An ignore rule can hide those ephemeral assets from continuous IaC tracking.
* **Third-party or externally managed resources**: You may have resources managed by external tools or other teams' IaC, which Firefly flags as unmanaged in your context. You can ignore those to focus on the assets you are responsible for.

By using IaC-Ignore rules judiciously, you ensure your IaC coverage and governance reports focus on relevant gaps only, filtering out assets that you deliberately want to leave unmanaged.


# Creating Exclude-Drift Rules

When Firefly detects a drift (a difference between the infrastructure as it exists in the cloud and what's defined in IaC), it alerts you so you can reconcile the change. However, not all drifts are important or actionable. An Exclude-Drift rule lets you ignore specific drift issues so that Firefly will stop alerting and notifying you about those particular differences. In effect, you are telling Firefly "I acknowledge this drift, but I want to exclude it from now on."

There are two ways to exclude drifts: by toggling an existing rule or by creating a new exclusion for a specific drift instance. Below is how you create a new drift exclusion rule for a drift you've identified.

1. **Go to Drifted assets**: In the Firefly console, navigate to the *Inventory* and filter to view the *Drifted* assets. This will list resources that have drifted from their IaC definitions.
2. **Select the asset with drift**: Find the resource that has the drift you want to ignore, and click on that asset's row to view details. In the asset detail pop-up, look for **Drift Details**, which will show the specific differences detected.
3. **Initiate drift exclusion**: Within the drift details, click the **Exclude Drift** button for that asset. This starts the process to define an exclusion rule for the drift.
4. **Configure the exclusion rule**: A dialog will prompt you to define the scope of the drift exclusion.
   * **Scope**: Choose the scope of assets the rule should apply to. You might limit it to just this one resource, or broaden it to a group (for example, all resources of a certain type or in a certain environment, if the drift is common).
   * **Properties**: Select the specific drift properties to ignore. Firefly will list the resource properties that have drifted (e.g., a tag value, a configuration field, etc.). You can pick which ones to exclude from drift detection. For instance, if an IAM policy document is drifted, you might choose to ignore just a particular policy statement difference.
   * **Data sources**: Optionally, specify the data source the rule applies to. This helps narrow down whether the exclusion is global or specific to certain integrations.
5. **Apply the exclusion**: Confirm by clicking Exclude. Firefly will save this drift exclusion rule. Going forward, the specified drift (those properties in that scope) will no longer trigger drift alerts or appear as an active drift in Firefly.

After excluding a drift, you can always review or manage these rules. In **Settings > Excluded Drifts**, you will find a list of all drift exclusion rules in effect. There you can search for specific rules and toggle them on or off. For example, if you want to start detecting that drift again, you can disable the exclusion rule by turning off its toggle.

## When to exclude a drift

Use drift exclusions for cases where a drift is known, acceptable, or not worth alerting on. Examples include:

* **Innocuous configuration changes**: Some drifts are harmless or expected. For instance, certain cloud-managed timestamps, random IDs, or auto-generated fields might always differ from IaC and don't need action. Excluding those prevents unnecessary noise. Firefly comes with built-in rules for some of these cases.
* **Accepted manual changes**: If a resource was intentionally changed manually (out-of-band) and you prefer to keep that change (not revert it in code), you can exclude that drift. This acknowledges the difference so Firefly won't flag it repeatedly. Essentially, you're telling Firefly to treat the IaC vs. actual mismatch as acceptable for that property.
* **Partial codification or known deviation**: You might have a case where most of a resource is managed in code, but a particular setting is intentionally managed in the cloud (perhaps due to a limitation or a one-time change). Creating an exclude-drift rule for that property spares you from seeing a perpetual drift alert.
* **Aligning with IaC ignore settings**: If you use Terraform, you may already use the `ignore_changes` meta-argument in your Terraform config for certain resource attributes. Firefly is aware of this, when your VCS is integrated, Firefly automatically ignores drifts for any resource properties marked with Terraform's `ignore_changes` in the lifecycle settings. This built-in behavior means you might not need a manual exclude rule for those, but it's good to know Firefly honors that by default. If a similar concept applies in other IaC tools, you'd handle it similarly.

Drift exclusions are a governance tool to fine-tune what you consider a real issue. They should be used sparingly and reviewed periodically, ensure that by ignoring a drift you're not overlooking something important. If circumstances change (e.g., you codify that property later), you should remove the exclusion so Firefly can resume drift detection for it.


# Policy & Governance

The Governance page in Firefly enables you to define, manage, and enforce compliance policies across your cloud and SaaS infrastructure and Infrastructure-as-Code (IaC) deployments. Using policy-as-code principles, Firefly helps you automate governance, ensure security compliance, and maintain best practices at scale.

Firefly's governance engine is built on the Open Policy Agent (OPA) framework and includes comprehensive built-in policies plus the ability to create custom rules tailored to your organization's needs.

## Key Features

### Built-in Policies

Firefly provides dozens of pre-configured policies covering:

* **Security**: Encryption, access controls, network security.
* **Compliance**: Industry standards (CIS, SOC2, PCI, etc.).
* **Cost Optimization**: Unused resources, rightsizing recommendations.
* **Best Practices**: Tagging, backup configurations, resource management, etc.

These policies are continuously updated by the Firefly team.

### Custom Policy Creation

Create organization-specific policies using multiple approaches:

* **No-Code Policy Builder**: Create governance rules without writing code using intuitive attribute-based or tags-based flows.
* **AI-powered generation**: Describe your requirements in plain English and generate Rego code automatically.
* **Rego code editor**: Write custom Open Policy Agent rules for advanced use cases.
* **Testing playground**: Validate policies against real assets before deployment.

### Continuous Monitoring

* **Real-time evaluation**: Policies run continuously against your infrastructure.
* **Compliance scoring**: Track compliance percentages for each policy.
* **Violation tracking**: Monitor policy violations with detailed remediation guidance.

### Automated Remediation

* **IaC patches**: Generate pull requests to fix violations in your Infrastructure-as-Code.
* **Cloud patches**: Provide CLI commands for direct cloud resource fixes.
* **Integration workflows**: Create tickets in Jira.

## Understanding the Governance Dashboard

When you navigate to the Governance page, you'll see a comprehensive view of your policy landscape:

### Policy Overview Table

Each policy displays:

* **Name and Category**: Clear identification and organization.
* **Severity Level**: Impact classification (Info, Low, Medium, High, Critical).
* **Compliance Percentage**: How many assets pass the policy check.
* **Violating Assets**: Count of resources that fail the policy with a link to the **Inventory** page, filtered to show only the assets that violate the policy.
* **Data Source & Asset Type**: Which cloud or SaaS providers and asset types the policy is applied to.
* **Remediation**: Available remediation options and recommendations.

### Policy Actions

For each policy, you can perform several key actions:

* **Remediate**: Remediate the policy violation by either generating a pull request to fix the violation in your Infrastructure-as-Code or by providing CLI commands for direct cloud resource fixes. For more information, see [Remediating Policy Violations](/detailed-guides/policy-and-governance/remediating-policy-violations).
* **View All Assets**: Click on the violating assets count to see a detailed list of all resources affected by the policy in the **Inventory** page. This opens a filtered view showing exactly which assets are violating the policy.
* **Create Notification Rules**: Set up automated alerts for policy violations by configuring notification rules. You can choose your preferred destination (Slack, Microsoft Teams, email, webhook, etc.) to receive real-time alerts when new violations occur.
* **Create Jira Issues**: Directly create Jira tickets for policy violations to track remediation efforts. This integration allows you to automatically generate issues with relevant context about the policy violation, ensuring governance issues are properly tracked and resolved.

### Filtering and Organization

Use the filter options to focus on specific areas:

* **Frameworks**: Filter by compliance standards (CIS, HIPAA, PCI, etc.).
* **Categories**: Focus on security, cost, encryption, etc.
* **Providers**: View policies for specific cloud or SaaS providers.
* **Data Sources**: View policies for specific cloud or SaaS providers.
* **Scopes**: View policies for specific asset types.
* **Severity**: Prioritize critical or high-severity violations.
* **Available Providers**: Show only policies that are available for the selected data source integrated on your Firefly account.
* **Production**: Show only violations that are in production data sources.
* **Violating Assets**: Show only policies that have violating assets.
* **Notifications**: Show only policies that have notifications configured.
* **Enabled**: Show only policies that are enabled.

## Working with Policies

### Creating New Policies

For detailed instructions on creating custom policies, see [Creating Policy-as-Code Rules](/detailed-guides/policy-and-governance/creating-policy-as-code-rules).

Key steps include:

1. **Define policy scope**: Select data sources and asset types.
2. **Set policy details**: Name, category, severity, and description.
3. **Create policy logic**: Choose from no-code builder (attribute-based or tags-based flows), AI generation, or manual Rego code.
4. **Test and validate**: Ensure the policy works as expected.
5. **Deploy and monitor**: Activate the policy for continuous evaluation.

### Managing Policy Violations

When violations occur, you have several remediation options. For complete guidance, see [Remediating Policy Violations](/detailed-guides/policy-and-governance/remediating-policy-violations).

**IaC Remediation (Recommended)**:

* Generate pull requests to fix violations in your Infrastructure-as-Code.
* Ensure fixes are version-controlled and properly reviewed.
* Maintain infrastructure drift prevention.

**Direct Cloud Remediation**:

* Apply fixes directly to cloud resources using provided CLI commands.
* Suitable for unmanaged resources or emergency fixes.
* Immediate compliance restoration.

### Integration with Development Workflows

Firefly integrates policy enforcement into your development lifecycle:

* **Pre-deployment scanning**: Prevent non-compliant resources from being deployed. For more information, see [Workflows & Guardrails](/detailed-guides/workflows).
* **Git integration**: Track policy violations back to specific code changes.
* **Notification systems**: Alert teams when new violations are detected.

## Best Practices for Implementation

### Getting Started

1. **Review built-in policies**: Disable non-relevant pre-configured rules.
2. **Start with high-severity items**: Focus on critical security and compliance issues.
3. **Establish baselines**: Understand your current compliance posture.
4. **Set up notifications**: Configure alerts for new violations.

### Scaling Governance

1. **Create custom policies**: Create custom policies to fit your needs. For more information, see [Creating Policy-as-Code Rules](/detailed-guides/policy-and-governance/creating-policy-as-code-rules).
2. **Implement gradual rollouts**: Phase in new policies across environments.
3. **Train development teams**: Ensure understanding of governance requirements.
4. **Regular policy reviews**: Keep rules current with changing requirements.
5. **Enforce policies**: Ensure policies are enforced on the deployment level. For more information, see [Workflows & Guardrails](/detailed-guides/workflows).

## Summary

Firefly's Policy & Governance capabilities provide comprehensive infrastructure governance through:

* **Automated policy enforcement** across multi-cloud and SaaS environments.
* **Continuous compliance monitoring** with real-time violation detection.
* **Intelligent remediation** through AI-powered fix generation.
* **Seamless integration** on IaC deployments and cloud resources.

By implementing policy-as-code practices with Firefly, you can maintain security, compliance, and operational excellence while enabling development teams to move quickly and confidently.

For specific implementation guidance, refer to:

* [Creating Policy-as-Code Rules](/detailed-guides/policy-and-governance/creating-policy-as-code-rules)
* [Remediating Policy Violations](/detailed-guides/policy-and-governance/remediating-policy-violations)


# Creating Policy-as-Code Governance Rules

Firefly provides two approaches for creating custom compliance and security policies that will be enforced across your cloud infrastructure and IaC deployments. These rules help ensure your cloud resources adhere to your organization's standards, security requirements, and best practices. Once created, Firefly will continuously evaluate your infrastructure against these policies and flag any violations, helping you maintain governance at scale.

Choose the approach that best fits your team's expertise and requirements:

***

## Option 1: No‑Code Policy Builder

The No‑Code Policy Builder allows you to define governance rules **without writing any code**. It's ideal for security, compliance, or platform teams who want quick policy creation without coding expertise. The No‑Code Builder includes two flows: **Attribute‑Based** and **Tags‑Based**.

### How to create a No‑Code policy:

1. **Open Governance page**: In the Firefly app, go to **Governance** page. This page allows you to manage all your governance policies.
2. **Add a new policy**: Click on **+ Custom Policy**. This will open the Create Custom Policy form.
3. **Select No‑Code Policy Builder**: Choose **No‑Code Policy Builder** as your policy type.
4. **Choose the flow type**: Select either **Attribute‑Based** or **Tags‑Based** depending on your requirements:
   * **Attribute‑Based**: For checking resource properties like encryption status, public access, instance types, etc.
   * **Tags‑Based**: For enforcing tagging requirements and standards.
5. **Configure policy details**: Fill in the Policy Details section:
   * **Name**: Give the policy a clear name (e.g., *Ensure all S3 buckets are encrypted*).
   * **Description**: Provide a clear description of what the policy checks and why it's important. This helps team members understand the policy's purpose.
   * **Severity**: Choose the severity level (LOW, MEDIUM, HIGH, CRITICAL) for violations.
   * **Data Source**: Select the cloud provider (e.g., AWS, Azure, GCP) or specific cloud accounts.
   * **Asset Type**: Choose the specific resource type to evaluate (e.g., AWS S3 Bucket, EC2 Instance).
6. **Define conditions**:

   **If Attribute‑Based**:

   * Pick an **Attribute** from the dropdown (e.g., `volume_encrypted`, `public_access`, `instance_type`).
   * Choose an **Operator**: `Is`, `Is Not`, or `Contains`.
   * Enter a **Value** for the condition.
   * Add multiple attributes as needed (conditions are combined with **AND** logic).

   **If Tags‑Based**:

   * Choose one of the following conditions:
     * **Tags Missing Entirely** – flags assets that have no tags at all.
     * **Specific Tag Missing** – requires specific tag keys like `owner`, `environment`, `project`.
     * **Specific Tag Value** – enforces exact tag values (e.g., `cost-center=finance`).
     * **Specific Tag Value — IS NOT** – disallows specific tag values (negative match).
7. **Save the policy**: Click **Create** to activate the policy. Firefly will begin evaluating your infrastructure against it and enforce it during IaC deployments.

### Example: No-Code Attribute-Based Policy

**Scenario**: Ensure all EC2 instances have EBS optimization enabled.

**Steps**:

1. **Asset Type**: Select "AWS EC2 Instance"
2. **Attribute**: Choose `ebs_optimized`
3. **Operator**: Select "Is"
4. **Value**: Enter `true`

This creates a policy that flags any EC2 instance where EBS optimization is not enabled, without requiring any code knowledge.

### Example: No-Code Tags-Based Policy

**Scenario**: Ensure all resources have required organizational tags.

**Steps**:

1. **Flow Type**: Select "Tags-Based"
2. **Condition**: Choose "Specific Tag Missing"
3. **Required Tags**: Enter `Environment`, `Owner`, `Project`

This creates a policy that flags any resource missing any of these required tags.

***

## Option 2: Policy-as-Code (Rego)

Policy-as-Code uses the Rego language (Open Policy Agent) to define custom governance rules. This approach provides maximum flexibility and allows you to create complex, highly specific policies for advanced use cases.

### How to create a Policy-as-Code rule:

1. **Open Governance page**: In the Firefly app, go to **Governance** page. This page allows you to manage all your governance policies.
2. **Add a new policy**: Click on **+ Custom Policy**. This will open the Create Custom Policy form.
3. **Select Policy-as-Code**: Choose **Policy-as-Code** as your policy type.
4. **Configure policy details**: Fill in the Policy Details section:
   * **Name**: Give the policy a clear name (e.g., *Ensure all S3 buckets are encrypted*).
   * **Category**: Select or create a category to organize your policies (e.g., Observability, Security, Compliance).
   * **Severity**: Choose the severity level (LOW, MEDIUM, HIGH, CRITICAL) for violations.
   * **Data Source**: Select the cloud provider (e.g., AWS, Azure, GCP) or specific cloud accounts.
   * **Asset Type**: Choose the specific resource type to evaluate (e.g., AWS S3 Bucket, EC2 Instance). Can be multiple resource types and even all resource types.
5. **Add policy description**: In the Policy description field, provide details about what the policy checks and why it's important. This helps team members understand the policy's purpose.
6. **Define the policy logic**: In the Rego Playground section, you have two options for creating your policy logic: **Option A: AI-Generated Code (Recommended)**

   * Click **"Generate with Thinkerbell AI"** to automatically generate Rego code based on your policy details.
   * Ensure you've provided a clear, descriptive policy description in step 4 for best AI results.
   * The AI will analyze your requirements and generate appropriate Rego code.
   * Review and modify the generated code as needed.

   **Option B: Manual Code Writing**

   * Write the policy logic manually using the Rego policy language (the language used by Open Policy Agent).
   * The playground provides:
     * A code editor with syntax highlighting.
     * An asset selector to choose a sample of resource data for viewing the input schema.
     * Input schema display showing the structure of data your policy will receive.
     * Real-time validation of your Rego code.
7. **Test the policy**:
   * Click **Evaluate** to test your Rego code.
   * Check the MATCHING RESULTS to see which resources would be affected.
8. **Save the policy**: Once your policy is working correctly (showing "Success" message), click **Create** to create the policy. The policy will be activated and Firefly will begin evaluating your infrastructure against it. The policy will also be enforced during IaC deployments to prevent non-compliant resources from being created.

After creating a policy, you can view violations in the Governance dashboard. Each violation will show which resource violated the policy and why, allowing you to take corrective action. If needed, you can always disable or delete the policy later via the **Governance** page.

### Example: S3 Bucket Encryption Policy

Here's a practical example of a Rego policy that ensures all AWS S3 buckets have server-side encryption enabled by default:

```rego
firefly {
  match
}

match {
  not input.rule.apply_server_side_encryption_by_default
}
```

**How this policy works:**

* **`firefly`**: This is the main rule that Firefly evaluates. When this rule is true, it means the resource violates the policy.
* **`match`**: This is a helper rule that contains the actual policy logic.
* **`not input.rule.apply_server_side_encryption_by_default`**: This condition checks if the S3 bucket configuration does NOT have server-side encryption enabled by default.

**Policy behavior:**

* If an S3 bucket has `apply_server_side_encryption_by_default` set to `true`, the `match` rule will be false, and the policy passes.
* If an S3 bucket has `apply_server_side_encryption_by_default` set to `false` or is missing this setting, the `match` rule will be true, flagging it as a violation.

**When to use this policy:** This policy is essential for organizations that need to ensure all S3 buckets are encrypted at rest to meet security and compliance requirements. It helps prevent accidental creation of unencrypted buckets and identifies existing buckets that need encryption enabled.

**Setting up this policy:**

1. Set **Asset Type** to "AWS S3 Bucket" when creating the policy.
2. Set **Data Source** to your AWS accounts.
3. Choose appropriate **Severity** (typically HIGH or CRITICAL for encryption policies).
4. Use the Rego code above in the policy logic section.

***

## After Creating a Policy

After creating a policy (whether no-code or policy-as-code), you can:

* **View violations** in the Governance dashboard. Each violation will show which resource violated the policy and why, allowing you to take corrective action.
* **Set up notifications** to alert your team when new violations occur.
* **Disable or delete** the policy later via the **Governance** page if needed.

## When to Create Custom Governance Rules

Creating custom governance policies is valuable in several scenarios:

* **Industry-specific compliance**: If your organization must adhere to specific regulations (like HIPAA, PCI-DSS, or GDPR), you can create policies that enforce those requirements across your cloud infrastructure.
* **Internal security standards**: Enforce your organization's security best practices, such as requiring MFA for all IAM users, preventing public access to sensitive resources, or ensuring proper encryption settings.
* **Cost optimization**: Create policies that identify wasteful resources, such as oversized instances, unused volumes, or resources without proper lifecycle management.
* **Tagging and organization**: Ensure all resources follow your tagging strategy by creating policies that check for required tags or naming conventions.
* **Architecture standards**: Enforce architectural best practices, such as requiring multi-AZ deployments for production databases or preventing the use of deprecated services.

> **Note**: Firefly comes with built-in policies for many common use cases. You can add custom policies to fit your specific organizational needs.

## Choosing Between No-Code and Policy-as-Code

**Use No-Code Policy Builder when:**

* You need quick policy creation without coding expertise.
* Your requirements fit standard attribute or tag-based conditions.
* You want to empower non-technical team members to create policies.
* You need simple, straightforward governance rules.

**Use Policy-as-Code (Rego) when:**

* You need complex, highly specific policy logic.
* Your requirements involve multiple conditions or advanced logic.
* You want maximum flexibility and customization.
* You have technical team members comfortable with code.

By implementing custom governance rules, you can automate compliance checking, reduce manual auditing efforts, and catch potential issues before they become problems. This proactive approach to governance helps maintain security and compliance at scale while still allowing teams to move quickly.


# Rego Packages

Rego Packages let you define shared Rego helper functions and data sets once and import them into any number of governance policies. When a package is updated, every policy that imports it automatically uses the new logic at its next evaluation — no per-policy edits required.

This is useful whenever the same logic needs to be enforced across multiple policies: tag validation helpers, approved resource lists, account classification rules, and similar shared constructs.

***

## How Rego Packages Work

Each package is a named module of Rego code stored under the `firefly.packages` namespace. A package named `tag_validator` is imported in a policy as:

```rego
import data.firefly.packages.tag_validator
```

At policy evaluation time, Firefly resolves all imported packages automatically. The latest version of each package is always used; there is no need to re-save a policy when a package is updated.

***

## Package Naming Rules

Package names must be valid Rego identifiers:

* Start with a letter (`a–z`, `A–Z`) or underscore (`_`)
* Followed by any combination of letters, digits, or underscores
* Maximum 128 characters
* Must be unique within your account

| Valid examples  | Invalid examples                |
| --------------- | ------------------------------- |
| `aws_helpers`   | `aws.helpers` (dot not allowed) |
| `IamChecks`     | `123check` (starts with digit)  |
| `tag_validator` | `my-pkg` (hyphen not allowed)   |
| `_internal`     | `http.send` (dot not allowed)   |

> **Note:** Package names cannot be changed after a package is created.

***

## Package Code Constraints

Package code is a standalone Rego module. It must follow these rules:

| Rule                  | Requirement                                                                         |
| --------------------- | ----------------------------------------------------------------------------------- |
| `package` declaration | Must **not** be included — Firefly injects it automatically                         |
| `import` statements   | Must **not** be included — packages are standalone and cannot import other packages |
| Restricted built-ins  | `http.send` and `opa.runtime` are not permitted                                     |
| Maximum size          | 50 KB                                                                               |
| Maximum line length   | 1,000 characters per line                                                           |
| Valid Rego            | Code must compile as valid OPA Rego                                                 |

The Rego editor validates your code in real time as you type, so you can catch errors before saving.

***

## Managing Packages

### Viewing Your Packages

Navigate to **Governance** and select **Policy Packages** from the menu. The list page shows all packages for your account, with columns for name and description. You can search by name or description using the search bar.

### Creating a Package

1. On the **Policy Packages** page, click the **Add Policy Package** button (top right).
2. In the **Package Details** section:
   * **Package Name** (required) — enter a name that follows the [naming rules](#package-naming-rules) above. This cannot be changed after the package is created.
   * **Description** (optional) — a plain-text description of what the package provides.
3. In the **Rego Code** section, write your package logic in the editor. Do not include a `package` declaration or any `import` statements.
   * The editor validates your code in real time. A **✓ Rego code is valid** indicator appears when the code compiles successfully.
4. Click **Create**. A confirmation message confirms the package was saved and you are returned to the package list.

**Example package code** — a set of tag validation helpers:

```rego
# Returns true if the resource has the specified tag key.
has_tag(resource, key) {
  resource.tags[key]
}

# Returns true if the resource has all of the specified tag keys.
has_all_tags(resource, keys) {
  count([k | k := keys[_]; has_tag(resource, k)]) == count(keys)
}
```

### Editing a Package

1. On the **Policy Packages** page, click the row actions menu (**⋮**) next to the package and select **Edit**.
2. Update the description or Rego code as needed. The package name cannot be changed.
3. Click **Save**. All policies that import this package will use the updated code at their next evaluation — no changes to those policies are required.

### Deleting a Package

1. On the **Policy Packages** page, click the row actions menu (**⋮**) next to the package and select **Delete**, or use the **Delete** button on the package edit page.
2. Confirm the deletion in the dialog that appears.

> **Warning:** Deleting a package is immediate and permanent. If any policies still contain an `import data.firefly.packages.<name>` statement for the deleted package, those policies will fail to compile at their next evaluation. Remove the import from any referencing policies before deleting a package.

***

## Using Packages in Policies

### Adding an Import

To use a package in a policy, add an import statement at the top of the policy's Rego code, after any existing imports:

```rego
import data.firefly.packages.<package_name>
```

Replace `<package_name>` with the exact name of the package you want to use. You must add this import to each policy that needs the package.

### Using Package Functions in Policy Rules

Once the import is in place, call the package's functions or reference its data using the package name as a prefix:

```rego
import data.firefly.packages.tag_validator

default firefly = false

firefly {
  tag_validator.has_all_tags(input, ["team", "env", "owner"])
}
```

### Import Validation

As you edit a policy's Rego code, Firefly automatically validates that every `import data.firefly.packages.*` statement refers to a package that exists in your account. If a referenced package is not found, a warning is shown in the editor. This check runs automatically as you type.

***

## Required Permissions

| Action                                      | Required Permission |
| ------------------------------------------- | ------------------- |
| View the package list or a specific package | `governance:read`   |
| Create a package                            | `governance:create` |
| Edit a package                              | `governance:update` |
| Delete a package                            | `governance:delete` |

For information on configuring roles and permissions, see [Access Management (RBAC)](/getting-started/access-management-rbac).


# Remediating Policy Violations

Policy violations occur when a cloud asset does not comply with one or more of your defined governance policies. Remediating these violations helps ensure your cloud environment remains secure, compliant, and aligned with best practices.

This guide explains how to remediate policy violations in Firefly, either by updating your Infrastructure as Code (IaC) to enforce the desired state or by applying changes directly in the cloud.

> **Note:** Promptly addressing policy violations reduces risk and helps maintain compliance.

## Before you begin

* Ensure your Version Control System (VCS) is integrated with Firefly (e.g., GitHub, GitLab) if you plan to remediate via IaC.
* Confirm you have the necessary permissions to update cloud resources and/or modify your IaC repositories.

## Procedure

**Go to Governance page**: In the Firefly console, navigate to **Governance** page. Locate the policy with violations and click on the **AI Remediation** button to view the remediation options.

### Option 1: IaC Patch (Recommended)

If the asset is managed by Infrastructure as Code (IaC), you can remediate by updating your codebase:

1. Choose **IaC Patch** option.
2. Select the IaC file you want to update and click on **Review fix**.
3. Review the proposed changes and click on **Create Pull Request**.
4. Firefly will generate a pull request to update your IaC source, ensuring the asset complies with the policy.
5. Review and merge the pull request in your VCS to apply the change.
6. Run a Terraform plan/apply or equivalent command to deploy the updated configuration.

```hcl
# Example: Terraform code snippet to enable encryption on an S3 bucket
resource "aws_s3_bucket" "example" {
  # ... existing configuration ...
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}
# This block enforces encryption at rest for the S3 bucket
```

### Option 2: Cloud Patch

If the asset is not managed by IaC (unmanaged), you can remediate directly in the cloud via given CLI commands:

1. Choose **Cloud Patch** option.
2. Select the asset you want to remediate.
3. Firefly will provide CLI commands to manually update the resource in your cloud provider.
4. Run the provided commands in your terminal or cloud console to bring the asset into compliance.

```bash
# Example: AWS CLI command to enable encryption on an S3 bucket
aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'
```

> **Tip:** Always review the proposed changes and test in a non-production environment when possible.

## Summary

* Policy violations indicate assets that do not comply with your governance rules.
* You can remediate violations by updating your IaC code (recommended for managed assets) or by applying changes directly in the cloud (for unmanaged assets).
* Firefly provides automated remediation suggestions and code/CLI snippets to help you resolve violations quickly.
* After remediation, re-scan your environment in Firefly to confirm compliance.


# Workflows

Welcome to the Firefly Workflows documentation. This guide provides a comprehensive overview of these powerful features, designed to streamline your Infrastructure as Code (IaC) deployments using Terraform, OpenTofu, and Terragrunt, while ensuring they adhere to your organization's standards. These features work within an organized project structure and leverage centralized configuration management to form a complete infrastructure automation and governance platform.

## Understanding Firefly Workflows

**Firefly Workflows** is a robust system designed to manage and automate your Terraform, OpenTofu, and Terragrunt deployments. It provides a centralized platform to control how your infrastructure code is planned and applied, integrating seamlessly with your Version Control System (VCS) and CI/CD practices. Workflows are organized within projects to provide clear boundaries and access controls, while leveraging reusable configuration collections to ensure consistent and scalable infrastructure management.

### What are Workflows?

In Firefly, a Workflow represents the end-to-end process of deploying a specific IaC stack. Each Workflow is tied to a **Workspace**, which encapsulates:

* **IaC Code:** The Terraform, OpenTofu, or Terragrunt configuration files defining a set of resources.
* **VCS Integration:** Connection to your Git repository (e.g., GitHub, GitLab) where the IaC code is hosted.
* **Variables:** Configuration values, including sensitive secrets, required for the deployment. These can be sourced from centralized variable sets or defined directly at the workspace level.
* **Execution Environment:** The setup used to run `plan` command.
* **Run History:** A log of all plan and apply operations performed for that Workspace.
* **Project Context:** The organizational unit that the workspace belongs to, which determines access control and inheritable configuration.

Workflows automate the critical steps of an IaC deployment:

1. **Plan on Change:** When changes are proposed to your IaC (typically via a pull request in your VCS), Firefly automatically triggers a `plan` command. This shows you the potential impact of the changes before they are made.
2. **Apply on Merge/Approval:** Once changes are approved and merged into your designated primary branch, Firefly triggers an `apply` command to enact those changes in your cloud environment.

### Key Benefits of Firefly Workflows:

* **Automation:** Reduces manual effort and potential for human error in deployments.
* **Consistency:** Ensures a standardized deployment process across all your projects and teams, with uniform configuration values managed centrally.
* **Visibility:** Provides a clear view of all ongoing and past deployments, their status, and detailed logs.
* **Collaboration:** Facilitates teamwork by integrating with VCS workflows (pull/merge requests) and providing shared visibility through project-based access control.
* **Control:** Allows for fine-grained configuration of how and when deployments occur.
* **Scalability:** Supports complex organizational structures through hierarchical organization and reusable configurations that eliminate duplication.

### Options for Using Workflows in Firefly

Firefly offers flexibility in how you can implement and utilize Workflows, catering to different needs and existing setups:

1. **Firefly-Managed Workflows (with Firefly Runners):**
   * **Concept:** Firefly provides and manages the execution environment (runners) for your Terraform/OpenTofu/Terragrunt operations. You define your Workspace in Firefly, point it to your IaC code in your VCS, and Firefly handles the rest, pulling the code, running `plan` and `apply` using its own secure and managed infrastructure.
   * **Best For:** Teams looking for a turnkey solution to automate IaC deployments without the overhead of managing their own CI/CD runners or complex pipeline scripts. Ideal for simplifying setup and getting started quickly.
   * **How it Works:** You create a new Workspace directly in the Firefly UI, configuring details like VCS repository, branch, Terraform/OpenTofu version, variables, and cloud provider authentication. Firefly's internal runners then execute the necessary Terraform/OpenTofu/Terragrunt commands based on triggers from your VCS (e.g., new pull request, merge to main branch).
   * Refer to the [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows) documentation for a detailed guide.
2. **Self-Hosted Runners:**
   * **Concept:** This model offers a hybrid approach where you host and manage the execution runners within your own environment, but these runners are specifically designated for and orchestrated by Firefly Workflows.
   * **Best For:** Organizations that require deployments to run within their own network boundaries for security or compliance reasons, while still benefiting from Firefly's Workflow management, UI, and Guardrail features.
   * **How it Works:** You would install and configure Firefly's runner agent in your infrastructure. When a Workflow is triggered, Firefly would delegate the `plan` or `apply` task to one of your self-hosted runners. These runners would then execute the Terraform/OpenTofu/Terragrunt commands, reporting status and logs back to Firefly.
   * Refer to the [Creating a Self-Hosted Runner Pool](/detailed-guides/workflows/creating-self-hosted-runner) documentation for a detailed guide.
3. **Integrate into Existing CI/CD Pipelines (Visualization and Monitoring):**
   * **Concept:** If you already have an established CI/CD pipeline (e.g., Jenkins, GitHub Actions, GitLab CI, Azure Pipelines) that handles your Terraform/OpenTofu/Terragrunt deployments, you can integrate Firefly to gain enhanced visualization, monitoring, and Guardrail enforcement for these existing processes.
   * **Best For:** Teams with mature CI/CD setups who want to leverage Firefly's insights, PR commenting, and Guardrail capabilities without overhauling their current deployment mechanisms.
   * **How it Works:** You continue to use your own CI/CD runners and pipeline scripts to execute `plan` and their corresponding `apply` commands. You add small steps to your pipeline using the `fireflyci` tool (a CLI or Docker image provided by Firefly). This tool sends the plan and apply logs and metadata from your CI/CD jobs to Firefly. Firefly then displays this information in its UI, providing a centralized view and allowing Guardrails to be evaluated.
   * Refer to the [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows) documentation for detailed instructions.

**Supported IaC Engines:** Firefly Workflows are designed to work seamlessly with:

* **Terraform**
* **OpenTofu**
* **Terragrunt**

> **Please note:** Supported Terragrunt Project Layouts

## Single module — inline (`applyAll = false`)

The `workingDirectory` contains both the `terragrunt.hcl` and the Terraform sources.

```
<repo-root>/
  <module>/                 ← workingDirectory = "<module>"
    terragrunt.hcl
    main.tf
    variables.tf
    outputs.tf
```

## Single module — parent source (`applyAll = false`)

The `workingDirectory` contains the `terragrunt.hcl` which references a parent directory as its module source (`source = ".."`).

```
<repo-root>/
  <module>/                 ← Terraform root module
    main.tf
    variables.tf
  <stack>/                  ← workingDirectory = "<stack>"
    terragrunt.hcl          ← source = ".."
```

## Multi-module (`applyAll = true`)

The `workingDirectory` is the root containing multiple environment stacks. Each subdirectory with a `terragrunt.hcl` is an independent module.

```
<repo-root>/
  <root>/                   ← workingDirectory = "<root>"
    <module>/               ← shared Terraform module (optional)
      main.tf
    <env-a>/
      terragrunt.hcl        ← source = "../<module>"
    <env-b>/
      terragrunt.hcl
    <env-c>/
      terragrunt.hcl
```

## Understanding Firefly Guardrails

**Firefly Guardrails** are a critical component for ensuring that your IaC deployments are safe, compliant, and align with your organization's policies. They act as automated checks that evaluate your `plan` output against a set of predefined rules.

### What are Guardrails?

Guardrails are policies you define within Firefly to govern your infrastructure changes. When a `plan` is generated by a Workflow (either Firefly-managed or an integrated external CI/CD pipeline sending data to Firefly), Guardrails analyze this plan to detect any violations of your configured rules.

If a violation is detected, Guardrails can:

* **Block the Deployment:** Prevent the `apply` from proceeding, thus stopping non-compliant changes before they reach your infrastructure.
* **Alert an Administrator:** Notify relevant personnel about the violation.
* **Allow Override (Flexible Block):** In some cases, authorized users can override a violation to allow a deployment to proceed, providing flexibility for exceptional circumstances.

### Key Benefits of Firefly Guardrails:

* **Proactive Policy Enforcement:** Catch and prevent policy violations before they become issues in your live environment.
* **Risk Mitigation:** Reduce the risk of security breaches, cost overruns, misconfigurations, and compliance failures.
* **Standardization:** Enforce consistent configurations and best practices across all your cloud resources.
* **Automation:** Automate policy checks, removing the need for manual reviews for many common policy requirements.
* **Developer Empowerment:** Provide developers with immediate feedback on policy compliance within their existing VCS and CI/CD workflows (e.g., via PR comments).

### Guardrail Rule Types

Firefly provides several types of Guardrail rules to cover various aspects of IaC governance:

1. **Cost Rules:**
   * **Purpose:** Control cloud spending by setting thresholds on estimated cost changes from a plan.
   * **Example:** Block any plan that estimates a cost increase of more than $100 or 10%.
2. **Policy Rules:**
   * **Purpose:** Enforce adherence to security best practices, compliance standards, or operational guidelines (using a policy engine like OPA).
   * **Example:** Ensure all S3 buckets have encryption enabled, or that no EC2 instances are created with public IP addresses.
   * **Comprehensive Coverage:** Can optionally evaluate existing resources that aren't being modified (no-op assets) to ensure all infrastructure meets policy requirements.
3. **Resource Rules:**
   * **Purpose:** Control specific actions (create, update, delete) on particular resource types, in certain regions, or for specific resource instances.
   * **Example:** Prevent the deletion of a critical database instance or disallow the creation of resources in a non-approved cloud region.
4. **Tag Rules:**
   * **Purpose:** Enforce consistent tagging policies for better resource organization, cost tracking, and automation.
   * **Example:** Require all resources to have an `Environment` tag, or ensure the `CostCenter` tag uses an approved value.
   * **Comprehensive Coverage:** Can optionally evaluate existing resources that aren't being modified (no-op assets) to ensure all infrastructure maintains proper tagging standards.

### Integrating Guardrails with Workflows

Guardrails are an integral part of the Firefly Workflow ecosystem:

* **During `plan` phase:** After a `plan` is generated, Firefly subjects it to evaluation by all applicable Guardrail rules defined for that Workspace's scope. This includes both planned changes and optionally existing resources (no-op assets) for Policy and Tag rules.
* **Feedback Loop:** Violations are reported back through various channels: in the Firefly UI (in a dedicated *Guardrails Step* for the run), as comments on pull requests, and via notifications (Slack, email, etc.).
* **AI-Powered Remediation:** For many violations, Firefly provides AI-generated suggestions and even code snippets to help developers quickly understand and fix the non-compliant IaC.

For a detailed guide on creating and managing these rules, refer to the [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules) documentation.

## Understanding Firefly Projects

**Firefly Projects** are organizational units designed to group and manage related Infrastructure as Code (IaC) orchestration resources like workspaces, variable sets, and self-hosted runners. Projects provide a structured approach to organizing complex deployments across multiple environments, teams, and applications while implementing robust access controls.

### What are Projects?

Projects in Firefly serve as the primary boundary for access control, resource organization, and operational management within Firefly Workflows. They enable teams to independently manage their infrastructure while maintaining clear separation between different environments, applications, or organizational units.

### Key Benefits of Firefly Projects:

* **Organizational Structure:** Group related workspaces, variables, and self-hosted runners by team, application, environment, or any logical boundary that matches your organization's needs.
* **Access Control:** Implement Role-Based Access Control (RBAC) to ensure users can only access resources within their assigned projects.
* **Resource Inheritance:** Leverage hierarchical variable inheritance and configuration sharing across project boundaries.
* **Operational Efficiency:** Set default configurations like drift detection schedules and notification settings at the project level.
* **Scalability:** Support complex organizational structures with up to 5 levels of project hierarchy.

### Project Structure and Hierarchy

Projects support a hierarchical structure that mirrors your organizational needs:

* **Organization Level (Root):** The top-level container for all projects, containing global resources accessible across all projects.
* **Project Level:** First level of organization-specific groupings (e.g., `/aws`, `/azure`, `/development`, `/production`).
* **Sub-Project Levels:** Further subdivision of projects up to 5 total levels (e.g., `/aws/production/frontend/web`).

### Project Components

Each project can contain:

* **Workspaces:** The core entity representing your IaC configuration, its associated VCS repository, variables, and run history.
* **Variable Sets:** Reusable collections of configuration variables.
* **Runner Pools:** Self-hosted execution environments (Firefly-managed or self-hosted).
* **Users:** Team members with specific role assignments.
* **Sub-Projects:** Nested organizational units.

### Variable Inheritance in Projects

Projects follow a hierarchical variable inheritance model:

* **Inheritance Flow:** Organization → Project → Sub-Project → Workspace.
* **Automatic Propagation:** Variables set on a project automatically inherit to all underlying projects and workspaces.
* **Precedence Rules:** Workspace variables override sub-project variables, which override project variables, which override organization variables.

## Understanding Firefly Variable Sets

**Firefly Variable Sets** are centralized, reusable collections of configuration variables that can be shared across workspaces and projects. They provide a powerful way to manage execution variables at scale while enforcing consistency across your Infrastructure as Code deployments.

### What are Variable Sets?

Variable Sets eliminate the need to duplicate configuration values across multiple workspaces while maintaining the flexibility to override values at specific scopes when needed. They serve as templates for common configuration patterns and enable centralized management of sensitive values like API keys, passwords, and certificates.

### Key Benefits of Firefly Variable Sets:

* **Centralized Management:** Define variables once and reuse them across multiple workspaces and projects.
* **Consistency Enforcement:** Ensure uniform configuration values across your infrastructure deployments.
* **Reduced Duplication:** Eliminate the need to manually configure the same variables across multiple workspaces.
* **Hierarchical Inheritance:** Leverage variable precedence rules and inheritance patterns to maintain flexibility.
* **Security Management:** Centrally manage sensitive values with proper access controls.
* **Conflict Detection:** Automatically detect and prevent variable conflicts across inheritance chains.

### Variable Set Scopes

Variable Sets can be created with different scopes:

* **Global Variable Sets:** Available across all projects and workspaces in the organization.
* **Project-Level Variable Sets:** Available only within specific projects and their sub-projects, with access restricted to users assigned to those projects.

### Variable Inheritance Hierarchy

Variables follow a hierarchical scope structure with specific inheritance and precedence rules:

1. **Organization Level:** Organization-wide variables that serve as defaults (lowest precedence).
2. **Project Level:** Project-specific variables that apply to all workspaces within the project.
3. **Sub-Project Level:** Sub-project-specific variables that apply to workspaces within the sub-project.
4. **Workspace Level:** Workspace-specific variables with the highest precedence.

**Precedence Order (highest to lowest):**

1. Workspace-level variables.
2. Variable set variables consumed by workspace.
3. Sub-project variables.
4. Project variables.
5. Organization-level variables.

## Related Guides and Examples

This documentation set will guide you through setting up and utilizing these features to their full potential. We encourage you to explore the specific guides for a deeper understanding of each component.

* [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): Step-by-step guide for setting up Firefly-managed workflows.
* [Path Configurations (Change-Based Triggers)](/detailed-guides/workflows/path-configurations): Trigger a workspace run when changes occur to files outside the workspace's configured working directory, including across repositories.
* [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows): How to connect your current CI/CD pipelines to Firefly for visualization and monitoring.
* [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
* [Wiz Policy Integration](/detailed-guides/workflows/wiz-policy-integration): Delegate IaC policy evaluation for a workspace's runs to Wiz, and block runs on the Wiz verdict.
* [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
* [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.
* [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.
* [SSH Private Module Access](/detailed-guides/workflows/ssh-private-module-access): Configure SSH-based access to private Git repositories containing Terraform modules.
* [Authentication using OIDC Provider](/detailed-guides/oidc-provider): Configure OpenID Connect (OIDC) authentication for secure AWS or Google Cloud access without static credentials.
* [Firefly Workflows Example Pipelines](https://github.com/gofireflyio/workflows-examples): Real-world pipeline and integration templates for Jenkins, GitHub Actions, and more.

## Conclusion

Firefly provides a comprehensive solution for automating and governing your Infrastructure as Code deployments. Whether you opt for Firefly-managed runners for simplicity, integrate Firefly into your existing CI/CD for enhanced visibility, or anticipate using self-hosted runners for greater control, the platform empowers you to deploy infrastructure with speed, confidence, and adherence to your organizational standards.

The organizational structure provides the access controls needed to manage complex multi-team environments, while centralized configuration management ensures consistency across your infrastructure. These capabilities work seamlessly with workflow automation and policy enforcement to create a unified platform that scales with your organization's needs.


# Creating Projects

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
> * [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.

Firefly Projects are organizational units designed to group and manage related Infrastructure as Code (IaC) orchestration resources like workspaces, variable sets, and self-hosted runners. By establishing project hierarchies, you can maintain clear separation of environments, teams, and applications, while implementing robust access controls. Projects serve as the primary boundary for access control, resource organization, and operational management within Firefly Workflows, enabling teams to independently manage their infrastructure and providing a structured approach to organizing complex deployments across multiple environments. This document provides a comprehensive guide on how to create and configure Projects in Firefly Workflows.

**Key Benefits of Using Projects:**

* **Organizational Structure:** Group related workspaces, variables, and self-hosted runner pools by team, application, environment, or any logical boundary that matches your organization's needs.
* **Access Control:** Implement Role-Based Access Control (RBAC) to ensure users can only access resources within their assigned projects.
* **Resource Inheritance:** Leverage hierarchical variable inheritance and configuration sharing across project boundaries.
* **Operational Efficiency:** Set default configurations like drift detection schedules and notification settings at the project level.
* **Scalability:** Support complex organizational structures with up to 5 levels of project hierarchy.

## Project Structure and Hierarchy

Firefly Projects support a hierarchical structure that mirrors your organizational needs:

### Project Hierarchy Levels

1. **Organization Level (Root):**
   * The top-level container for all projects.
   * Contains global resources accessible across all projects.
   * Houses the default project that serves as the root directory.
2. **Project Level:**
   * First level of organization-specific groupings.
   * Examples: `/aws`, `/azure`, `/development`, `/production`.
3. **Sub-Project Levels (up to 5 total levels):**
   * Further subdivision of projects.
   * Examples: `/aws/production`, `/aws/production/frontend`, `/aws/production/frontend/web`.

### Project Components

Each project can contain:

* **Workspaces:** Terraform/OpenTofu/Terragrunt execution environments.
* **Variable Sets:** Reusable collections of configuration variables.
* **Runner Pools:** Self-hosted execution environments.
* **Users:** Team members with specific role assignments.
* **Sub-Projects:** Nested organizational units.

### Variable Inheritance

Projects follow a hierarchical variable inheritance model that distinguishes between direct variable assignment and variable set access:

#### Direct Variable Inheritance

* **Inheritance Flow:** Organization → Project → Sub-Project → Workspace.
* **Automatic Propagation:** When you set variables directly on a project, all underlying projects and workspaces automatically inherit those variables.
* **Precedence Rules:** Workspace variables override sub-project variables, which override project variables, which override organization variables.
* **Example:** If you set `AWS_REGION=us-east-1` on the `/aws` project, all sub-projects like `/aws/production` and `/aws/development`, as well as all workspaces within them, will automatically have access to this variable.

#### Variable Set Access Control

* **First-Level Assignment:** Variable set assignment to projects can only occur at the first level of the hierarchy.
* **Automatic Sub-Project Access:** When you assign a variable set to a project, all sub-projects and workspaces within them can consume that variable set.
* **Access-Based Assignment:** Assigning a variable set to a project is different from direct variable inheritance. It controls **who can view and use** that variable set.
* **User Scope:** Only users who have access to that project and its sub-projects can view and use the assigned variable set.
* **Selective Consumption:** Child resources can choose to consume variable sets from their parent projects, but the variable set must be accessible to the user performing the assignment.
* **Example:** If you assign a variable set called `aws-production-secrets` to the `/aws` project, only users with access to `/aws` and its sub-projects can view and use this variable set when creating workspaces or sub-projects.

#### User Access and Project Visibility

* **First-Level Assignment:** User assignment to projects can only occur at the first level of the hierarchy.
* **Automatic Sub-Project Access:** Users assigned to a Level 1 project automatically gain visibility and access to all sub-projects beneath it.
* **Inherited Permissions:** The role assigned to the user at Firefly organization level applies to all projects and sub-projects, ensuring consistent access control throughout the hierarchy.
* **Example:** A user assigned as *Admin* in Firefly and assigned to the `/aws` project automatically has Admin access to the `/aws` project and all sub-projects, including `/aws/production`, `/aws/development`, and all workspaces within these sub-projects.

## Creating a New Project: Step-by-Step

Follow the wizard in the Firefly UI to create a new Project.

**Procedure:**

U\[1. **Navigate to Projects & Variables:** \* In the Firefly UI, click on **Workflows** from the main navigation menu. \* Then, click on the **Projects & Variables** sub-section.

2. **Add New Project:**
   * Click on the **+ Create new project** button.
3. **Enter Project Details:**
   * **Name:**
     * Provide a unique name for your project (3-64 characters).
     * Use alphanumeric characters, hyphens, and underscores only.
     * The name must be unique within the selected parent directory.
     * *Example:* `aws-production`, `frontend-services`, `data-platform`.
   * **Description (Optional):**
     * Add a free-text explanation to help identify the project's purpose.
     * *Example:* "Production AWS infrastructure for customer-facing applications".
4. **Configure Project Hierarchy:**
   * **Parent Project (Optional):**
     * Select a parent project if this is a sub-project.
     * Projects can nest up to 5 levels deep.
     * Leave blank to create a root-level project.
     * *Example:* Select `/aws` as parent for a `/aws/production` sub-project.
5. **Configure Runner Pool:**
   * **Runner Pool (Optional):**
     * Please refer to the "Runner Pool Inheritance" section for more details.
     * Default: No runner pool assigned (workspaces use Firefly-managed runners)
     * Selection: Choose from available self-hosted runner pools in your organization
     * Inheritance: All workspaces and sub-projects inherit this runner pool assignment automatically
     * Leave empty if you want workspaces to use Firefly's managed runners or if you'll assign runner pools at the workspace level.
6. **Add Classification Labels:**
   * **Labels (Optional):**
     * Add tags to categorize or filter projects.
     * Use existing labels from the dropdown or create new ones.
     * *Example:* `environment:production`, `team:platform`, `cost-center:engineering`.
7. **Assign Users and Permissions:**
   * **User Assignment (Optional):**
     * Select users who should have access to this project.
     * Users will receive permissions based on their assigned roles.
     * **Available Roles:**
       * **Viewer:** Can view project assets and resources.
       * **Admin:** Can create, update, and delete project resources.
     * Users assigned to parent projects automatically inherit access to sub-projects.
8. **Configure Periodic Plan for Drift Detection:**
   * **Set Default Periodic Plan (Optional):**
     * Enable automatic drift detection for all workspaces in this project.
     * **Simple Configuration:**
       * Check the box to enable periodic plans.
       * Set frequency: "Once every X hours" (e.g., 5 hours).
     * **Advanced Configuration:**
       * Click the rotation icon to convert to full cron expression.
       * Enter custom cron pattern (minimum frequency: hourly).
       * *Example:* `0 */5 * * *` for every 5 hours.
9. **Configure Project Variables:**
   * **Variable Set Selection (Optional):**
     * Choose one or more reusable variable sets to inherit.
     * Variable sets can be defined at organization or project level.
     * **Conflict Resolution:** If multiple variable sets contain the same variable name, you'll see a warning and must resolve the conflict.
   * **Custom Variables (Optional):**
     * Define project-specific variables that will be inherited by all child resources.
     * **Variable Properties:**
       * **Name:** The variable key (must be unique within the project).
       * **Value:** The variable value (can be overridden at workspace level).
       * **Sensitive:** Mark as sensitive to hide the value in logs and UI.
       * **Environment Variable:** Export as environment variable during execution.
10. **Review and Create:** \* Carefully review all configured settings for your project. \* Ensure the hierarchy, user assignments, and variable configurations are correct. \* Click **Create** to create the project.

## Runner Pool Inheritance

When you assign a self-hosted runner pool to a project, all workspaces within that project and its sub-projects automatically use that runner pool for execution. Workspace-level runner assignments override project-level assignments. For detailed information on creating and managing runner pools, see [Creating a Self-Hosted Runner Pool](/detailed-guides/workflows/creating-self-hosted-runner).

## After Creating a Project

* **Activation:** The project becomes active immediately and is available for workspace creation and resource assignment.
* **Workspace Creation:** When creating new workspaces, the project will appear in the project assignment dropdown.
* **Variable Inheritance:** All variables and variable sets configured at the project level will automatically be available to child resources.
* **Access Control:** Users assigned to the project will gain access to all project resources according to their roles.
* **Drift Detection:** If configured, automatic drift detection will begin running for all workspaces created within the project.

## Managing Projects

Once created, you can manage your projects through various operations:

### Viewing and Filtering Projects

* **Project List View:** The **Projects & Variables** page displays all projects you have access to.
* **Search and Filter:**
  * **Text Search:** Search by project name, description, or labels.
  * **Hierarchy Navigation:** Expand and collapse project hierarchies.
  * **Column Sorting:** Sort by name, user count, workspace count, or other attributes.

### Editing Projects

* **Basic Information:** Update name, description, parent project, and labels.
* **User Management:** Add or remove users.
* **Periodic Plan for Drift Detection:** Modify periodic plan schedules.
* **Variable Configuration:** Access through the *Edit Variables* option in the actions menu.

### Variable Management

* **Variable Sets:** Attach or detach variable sets from projects.
* **Custom Variables:** Add, modify, or remove project-specific variables.
* **Inheritance Tracking:** View variable origins and override indicators.
* **Conflict Resolution:** Resolve conflicts between variable sets with duplicate keys.

### Deleting Projects

* **Workspace Handling:** Choose to delete associated workspaces or transfer them to the parent project.
* **Resource Cleanup:** Optionally run IaC destroy operation before deleting workspaces.
* **Confirmation Required:** Type the exact project name to confirm deletion.

## Examples of Project Structures

Here are some practical examples of how to organize projects:

### Environment-Based Organization

```
Organization
├── development/
│   ├── frontend/
│   └── backend/
├── staging/
│   ├── frontend/
│   └── backend/
└── production/
    ├── frontend/
    └── backend/
```

### Cloud Provider Organization

```
Organization
├── aws/
│   ├── production/
│   │   ├── us-east-1/
│   │   └── us-west-2/
│   └── development/
├── azure/
│   ├── production/
│   └── development/
└── gcp/
    ├── production/
    └── development/
```

### Team-Based Organization

```
Organization
├── platform-team/
│   ├── infrastructure/
│   └── monitoring/
├── frontend-team/
│   ├── web-apps/
│   └── mobile-apps/
└── data-team/
    ├── analytics/
    └── ml-pipelines/
```

## Best Practices for Creating Projects

* **Plan Your Hierarchy:** Design your project structure before creating projects. Consider your organization's structure, deployment patterns, and access control requirements.
* **Use Meaningful Names:** Choose descriptive names that clearly indicate the project's purpose and scope.
* **Leverage Labels:** Use consistent labeling conventions to enable effective filtering and organization.
* **Design Variable Inheritance:** Plan your variable inheritance strategy to minimize duplication and ensure consistency.
* **Start Simple:** Begin with a basic project structure and expand as your needs grow.
* **Document Your Structure:** Maintain documentation explaining your project hierarchy and naming conventions.
* **Regular Review:** Periodically review and optimize your project structure as your organization evolves.
* **Use Periodic Plan for Drift Detection Wisely:** Configure appropriate drift detection schedules that balance monitoring needs with resource consumption.
* **Consider Compliance:** Ensure your project structure supports any regulatory or compliance requirements.

## Project Permissions and RBAC

Understanding the Role-Based Access Control (RBAC) system is crucial for effective project management:

### Role Definitions

* **Viewer:**
  * Can view project assets and resources.
  * Cannot modify configurations or trigger deployments.
  * Suitable for stakeholders who need visibility without operational access.
* **Admin:**
  * Can create, update, and delete project resources.
  * Can manage workspaces, variable sets, and self-hosted runner pools.
  * Can assign users and modify project configurations.
  * Suitable for team leads and infrastructure operators.

### Permission Inheritance

* **Project Hierarchy:** Users with admin role in a project automatically have admin access to all sub-projects.
* **Resource Access:** Project membership determines access to workspaces, variable sets, and self-hosted runner pools within the project.
* **Global Access:** Some resources can be marked as global, making them accessible across all projects.

By thoughtfully creating and managing projects, you can build a scalable, secure, and well-organized infrastructure management system that grows with your organization's needs.


# Creating Variable Sets

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
> * [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
> * [Wiz Policy Integration](/detailed-guides/workflows/wiz-policy-integration): Uses the `Wiz Policy Integration Authentication` variable set template to delegate policy evaluation to Wiz.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.

Variable Sets in Firefly Workflows are centralized, reusable collections of configuration variables that can be shared across workspaces and projects. They provide a powerful way to manage execution variables at scale, and enforce consistency across your Infrastructure as Code (IaC) deployments. Variable Sets eliminate the need to duplicate configuration values across multiple workspaces while maintaining the flexibility to override values at specific scopes when needed. This document provides a comprehensive guide on how to create, manage, and utilize Variable Sets effectively in Firefly Workflows.

**Key Benefits of Using Variable Sets:**

* **Centralized Management:** Define variables once and reuse them across multiple workspaces and projects.
* **Consistency Enforcement:** Ensure uniform configuration values across your infrastructure deployments.
* **Reduced Duplication:** Eliminate the need to manually configure the same variables across multiple workspaces.
* **Hierarchical Inheritance:** Leverage variable precedence rules and inheritance patterns to maintain flexibility.
* **Security Management:** Centrally manage sensitive values like API keys, passwords, and certificates.
* **Conflict Detection:** Automatically detect and prevent variable conflicts across inheritance chains.

## Variable Sets Structure and Inheritance

Variable Sets in Firefly follow a sophisticated inheritance model that provides both flexibility and consistency:

### Variable Inheritance Hierarchy

Variables in Firefly follow a hierarchical scope structure with specific inheritance and precedence rules:

1. **Organization Level (Global):**
   * Organization-wide variables that serve as defaults for all projects and workspaces.
   * Lowest precedence in the inheritance chain.
   * Can be overridden at any lower scope.
2. **Project Level:**
   * Project-specific variables that apply to all workspaces within the project.
   * Override organization-level variables.
   * Inherited by all sub-projects and workspaces.
3. **Sub-Project Level:**
   * Sub-project-specific variables that apply to workspaces within the sub-project.
   * Override project-level variables.
   * Inherited by workspaces within the sub-project.
4. **Workspace Level:**
   * Workspace-specific variables with the highest precedence.
   * Override all inherited variables.
   * Final values used during execution.

### Variable Precedence Rules

**Precedence Order (highest to lowest):**

1. Workspace-level variables.
2. Variable set variables consumed by workspace.
3. Sub-project variables.
4. Project variables.
5. Organization-level variables.

### Variable Set Scopes

Variable Sets can be created with different scopes:

* **Global Variable Sets:** Available across all projects and workspaces in the organization. All users can view these variable sets and Admin users can edit them.
* **Project-Level Variable Sets:** Available only within specific projects and their sub-projects. Only users assigned to those projects can access and view these variable sets.

### Variable Set Inheritance Rules

* **Association vs. Consumption:** Variable sets can be *associated* with projects (making them available) and *consumed* by workspaces, projects, sub-projects, and organization-level (actively using their values). Only users assigned to the project can access and view these variable sets.
* **Conflict Resolution:** When multiple variable sets contain the same variable name at the same hierarchy level, conflicts must be resolved before consumption.
* **Override Capability:** Variables from consumed variable sets can be overridden by workspace-specific, project-specific, sub-project-specific, and organization-level variables.

## Creating a New Variable Set: Step-by-Step

Follow the wizard in the Firefly UI to create a new Variable Set.

**Procedure:**

1. **Navigate to Projects & Variables:**
   * In the Firefly UI, click on **Workflows** from the main navigation menu.
   * Then, click on the **Projects & Variables** sub-section.
2. **Create New Variable Set:**
   * Click on the **+ Create new variable set** button.
3. **Select Variable Set Template:** (*Optional*)
   * Select the template you want to use for your variable set.
   * The template will be used to populate the variable set with the default variables.
   * You can always edit the variables after selecting the template.
   * *Example:* Select the `AWS Cloud Credentials` template to populate the variable set with the default AWS credentials variables.
   * *Example:* Select the `Wiz Policy Integration Authentication` template to populate the variable set with the Wiz service account variables. Consuming this set is what enables the [Wiz Policy Integration](/detailed-guides/workflows/wiz-policy-integration) for a workspace.
4. **Enter Variable Set Details:**
   * **Name:**
     * Provide a unique name for your variable set (3-64 characters).
     * Use alphanumeric characters, hyphens, and underscores only.
     * The name must be unique across the organization.
     * *Example:* `aws-production-secrets`, `common-terraform-vars`, `dev-environment-config`.
   * **Description (Optional):**
     * Add a free-text explanation to describe the variable set's purpose.
     * *Example:* "Production AWS credentials and configuration for customer-facing applications".
5. **Configure Project Assignment:**
   * **Project Assignment (Optional):**
     * Select one or more projects to assign this variable set to.
     * If no projects are selected, the variable set becomes globally available.
     * Only workspaces and sub-projects under assigned projects can consume this variable set.
     * Only users assigned to the project can access and view these variable sets.
     * *Example:* Assign to `/aws` project to make it available only to AWS-related workspaces and sub-projects.
6. **Define Variables:**
   * **Variable Configuration:**
     * Add individual variables to the set.
     * Each variable requires a name and value.
     * **Variable Properties:**
       * **Name:** The variable key (must be unique within the set).
       * **Value:** The variable value (can be overridden at lower scopes).
       * **Sensitive:** Mark as sensitive to hide the value in logs and UI.
       * **Environment Variable:** Export as environment variable during execution.
   * **Variable Management:**
     * **Add Variables:** Use *Add new* for single variables or *Multiple at once* for bulk addition.
     * **Search and Filter:** Use the search input to find specific variables.
     * **Override Indicators:** Variables with override warnings show the original source.
     * **Conflict Resolution:** Address any conflicts between variables.
7. **Review and Create:**
   * Carefully review all configured variables and settings.
   * Ensure no conflicts exist between variables.
   * Verify that sensitive variables are properly marked.
   * Click **Create** to create the variable set.

## Managing Variable Sets

Once created, Variable Sets can be managed through various operations:

### Viewing and Searching Variable Sets

* **Variable Sets List View:** The **Projects & Variables** page displays all sets you have access to.
* **Search and Filter:**
  * **Text Search:** Search by variable set name or description.
  * **Column Sorting:** Sort by name, projects assigned, workspace usage, or variable count.

### Editing Variable Sets

* **Basic Information:** Update name, description, and project assignments.
* **Variable Management:** Add, modify, or remove variables from the set.
* **Conflict Resolution:** Address conflicts that arise from variables changes.
* **Edit Validation:** Before saving, the system will validate the variable set to ensure it is valid and does not contain conflicts in the inheritance chain.

### Variable Set Assignment and Consumption

* **Project Assignment:** Associate variable sets with specific projects to control access.
* **Consumption:** Organization, projects, sub-projects, and workspaces can consume variable sets to inherit their variables.
* **Bulk Operations:** Assign variable sets to multiple projects simultaneously.

### Deleting Variable Sets

* **Impact Analysis:** View all affected consumers (projects, sub-projects, and workspaces) before deletion.
* **Confirmation Required:** Type the exact variable set name to confirm deletion.
* **Irreversible Action:** Deletion permanently removes the set from all consuming resources.

## Variable Inheritance Scenarios

Understanding how variables inherit and override each other is crucial for effective variable set management:

### Scenario 1: Basic Inheritance

**Given:**

* Organization has variable `env = "global"`.
* Project `/aws` has variable `env = "aws"`.
* Variable set `prod-config` (consumed by workspace) has `env = "production"`.
* Workspace `/aws/app` has variable `env = "app"`.

**Result:** Workspace uses `env = "app"` (workspace value takes highest precedence).

### Scenario 2: Conflict Resolution

**Given:**

* Variable set A has `api_key = "key-from-a"`.
* Variable set B has `api_key = "key-from-b"`.
* Workspace attempts to consume both sets.

**Result:** Conflict error - "Variable sets A and B have conflicts on variables: api\_key".

### Scenario 3: Multiple Inheritance Levels

**Given:**

* Organization variable: `stage = "dev"`.
* Project variable set: `stage = "test"`.
* Workspace variable: `stage = "prod"`.

**Result:** Workspace uses `stage = "prod"` (workspace variable overrides all inherited values).

## Setting Organization Variables

Organization variables serve as the foundation of your variable inheritance hierarchy:

**Procedure:**

1. **Access Organization Variables:**
   * From the **Projects & Variables** page, click **Organization Variables**.
2. **Configure Global Defaults:**
   * **Variable Properties:**
     * **Name:** Organization-wide variable name.
     * **Value:** Default value for all projects and workspaces.
     * **Sensitive:** Mark sensitive values appropriately.
     * **Environment Variable:** Export as environment variable.
3. **Save Configuration:**
   * Click **Save** to apply organization-wide defaults.

## Examples of Variable Set Structures

Here are practical examples of how to organize variable sets:

### Environment-Based Variable Sets

```
Organization Variables:
├── terraform_version = "1.5.0"
├── company_name = "acme-corp"
└── default_region = "us-east-1"

Variable Sets:
├── base-terraform-config
│   ├── terraform_version = "1.5.0"
│   └── provider_version_constraints = "~> 5.0"
├── aws-production-secrets
│   ├── aws_access_key_id = "***" (sensitive)
│   ├── aws_secret_access_key = "***" (sensitive)
│   └── aws_region = "us-east-1"
└── development-overrides
    ├── aws_region = "us-west-2"
    └── instance_type = "t3.micro"
```

### Project-Specific Variable Sets

```
Project-Level Variables:
├── owner = "platform-team"
├── managed_by = "firefly"
└── environment = "unspecified"

Project-Assigned Variable Sets:
├── aws-credentials (assigned to /aws project)
│   ├── aws_access_key_id = "***" (sensitive)
│   └── aws_secret_access_key = "***" (sensitive)
├── azure-credentials (assigned to /azure project)
│   ├── azure_client_id = "***" (sensitive)
│   └── azure_client_secret = "***" (sensitive)
└── production-config (assigned to /production project)
    ├── environment = "production"
    └── monitoring_enabled = "true"
```

## Best Practices for Variable Sets

* **Plan Your Inheritance Strategy:** Design your variable set hierarchy before creating sets to avoid conflicts and ensure efficient inheritance.
* **Use Meaningful Names:** Choose descriptive names that clearly indicate the variable set's purpose and scope.
* **Leverage Inheritance:** Use variable set inheritance to create base configurations that can be extended for specific use cases.
* **Manage Sensitive Values:** Always mark sensitive variables appropriately and avoid exposing secrets in logs or UI.
* **Document Your Sets:** Use descriptions to explain the purpose and intended usage of each variable set.
* **Regular Review:** Periodically review variable sets to remove unused variables and optimize inheritance chains.
* **Test Inheritance:** Verify that variable inheritance works as expected by checking effective variables at the workspace level.
* **Avoid Deep Inheritance:** Keep inheritance chains shallow to maintain clarity and avoid complex conflict resolution.
* **Use Project Assignment:** Assign variable sets to specific projects to implement proper access control.
* **Monitor Usage:** Track which workspaces consume each variable set to understand impact before making changes.

## Variable Set Security and Governance

Implementing proper security and governance practices for variable sets is essential:

### Security Best Practices

* **Sensitive Variable Management:**
  * Always mark credentials, API keys, and passwords as sensitive.
  * Use environment variables for secrets that should not appear in Terraform/OpenTofu/Terragrunt configurations.
  * Regularly rotate sensitive values and update variable sets accordingly.
* **Access Control:**
  * Assign variable sets to specific projects to limit access.
  * Use global variable sets sparingly and only for truly universal values.
  * Regularly review project assignments and user access.

### Governance Practices

* **Change Management:**
  * Implement approval processes for changes to production variable sets.
  * Document changes and their impact on consuming workspaces.
  * Test changes in non-production environments first.
* **Audit and Compliance:**
  * Track variable set usage across workspaces and projects.
  * Monitor for unused or duplicated variable sets.
  * Maintain documentation of variable set purposes and owners.

## Troubleshooting Common Issues

### Conflict Resolution

**Problem:** Variable sets contain conflicting variables. **Solution:**

* Review conflicting variable sets and resolve conflicts.
* Use variable precedence rules to determine which value should take priority.
* Consider splitting conflicting sets into separate, more specific sets.

### Missing Variables

**Problem:** Workspace cannot access expected variables from a variable set. **Solution:**

* Verify the variable set is properly assigned to the workspace's project.
* Check if the workspace is consuming the variable set.
* Ensure the user has proper permissions to access the variable set.

### Inheritance Issues

**Problem:** Variable inheritance is not working as expected. **Solution:**

* Review the inheritance hierarchy and precedence rules.
* Check for conflicts between variables in the inheritance chain.
* Verify that variable sets are properly configured with inheritance relationships.

By following this comprehensive guide, you can effectively create, manage, and utilize Variable Sets in Firefly Workflows to streamline your infrastructure management, enforce consistency, and implement proper governance across your organization's IaC deployments.


# Creating Workflows

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows): For hybrid or external CI/CD integration.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
> * [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
> * [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.
> * [SSH Private Module Access](/detailed-guides/workflows/ssh-private-module-access): Configure SSH-based access to private Git repositories for Terraform modules.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.
> * [Path Configurations (Change-Based Triggers)](/detailed-guides/workflows/path-configurations): Trigger a workspace run when changes occur to files outside the workspace's configured working directory, including across repositories.
> * [Firefly Workflows Example Pipelines](https://github.com/gofireflyio/workflows-examples): Real-world pipeline and integration templates for Jenkins, GitHub Actions, and more.

Firefly Workflows offer a streamlined and powerful way to automate your Terraform, OpenTofu, and Terragrunt deployments directly within the Firefly platform. When you choose to create a new IaC pipeline with Firefly Runners, you leverage Firefly's fully managed infrastructure to execute your IaC operations (`plan` and `apply`). This approach provides built-in drift detection, policy guardrails, automatic logging, and a secure, scalable experience for your infrastructure deployments. For organizations with specific security or compliance needs, Firefly also supports self-hosted runners, allowing you to run workflows within your own environment while still benefiting from Firefly's orchestration and governance features.

This document provides a comprehensive guide to creating and configuring a new Firefly Runners-managed workflow.

## Introduction to Firefly Runners

Firefly Runners are ideal for:

* **Fully Managed IaC Operations**: Firefly handles the entire execution environment, eliminating the need to configure and maintain your own runners or complex pipeline scripts.
* **Built-in Drift Detection**: Automatic periodic scanning to detect infrastructure drift, configuration changes and deployment failures.
* **Policy Guardrails**: Integrated policy enforcement with automated checks and violations reporting.
* **Secure Execution**: Firefly provides a secure, isolated environment for running your Terraform/OpenTofu/Terragrunt operations.
* **Automated Logging**: Comprehensive logging and audit trails for all IaC operations.
* **VCS Integration**: Seamless integration with your Version Control System (VCS) like GitHub, GitLab, etc.
* **Flexible Runner Options**: Choose between managed runners for simplicity or self-hosted runners for enhanced security, compliance, and network control.

Each workflow in Firefly corresponds to a **Workspace**. A Workspace represents a specific IaC stack (a collection of Terraform/OpenTofu/Terragrunt files defining a set of resources) and its deployment configuration.

**Key Concepts for Firefly Runners:**

* **Workspace**: The core entity representing your IaC configuration, its associated VCS repository, variables, and run history.
* **Firefly Runners**: Firefly offers two types of runners for executing your IaC commands (`plan`, `apply`, and others):
  * **Managed Runners**: Firefly's fully managed, cloud-hosted infrastructure that securely runs your IaC operations without any setup or maintenance required on your end.
  * **Self-Hosted Runners**: For organizations with strict security, compliance, or network requirements, Firefly supports self-hosted runners. These allow you to run all IaC operations within your own environment or network, giving you full control over execution, networking, and data residency. Self-hosted runners are ideal when you need to keep sensitive credentials or resources within your own infrastructure.
* **VCS Integration**: Connects Firefly to your Git provider (e.g., GitHub) to trigger workflows based on code changes (pull requests, merges).
* **Pull Request (PR) Trigger**: Optionally, creating a PR in your connected repository automatically triggers a `plan` for the corresponding Workspace.
* **Merge Trigger**: Optionally, merging a PR into the Workspace's default branch automatically triggers a `apply` (or waits for manual approval, depending on Workspace settings).
* **Periodic Plans**: Optionally, scheduled drift detection that runs periodic `plan` operations to identify infrastructure changes and alert on deployment failures.

## Prerequisites

Before creating a Firefly Runners workflow, ensure you have:

* An active Firefly account with appropriate permissions to create Workflows and Workspaces.
* Your Terraform, OpenTofu, or Terragrunt code hosted in a supported Version Control System (e.g., GitHub, GitLab, Azure DevOps, etc.).
* Your VCS provider integrated with Firefly. This is done at an organizational level within Firefly settings.
* Understanding of your IaC project structure (working directory, variable files, etc.).

## Creating a New Firefly Runners Workflow: Step-by-Step

Follow the wizard in the Firefly UI to create a new workspace with Firefly Runners.

**Procedure:**

### Step 1: Navigate to Workspaces:

In the Firefly UI, click on **Workflows > Workspaces** from the main navigation menu.

### Step 2: Add New Workspace:

Click on the **+ Add New Workspace** button.

### Step 3: Choose Workflow Type:

Select from the two available options:

#### Create new IaC pipeline (Firefly Runners) *Recommended*

Firefly will fully manage IaC operations using its execution engine, with built-in drift detection, policy guardrails, and automatic logging. This option supports both managed runners (Firefly's cloud infrastructure) and self-hosted runners (your own infrastructure) for maximum flexibility and security.

#### Integrate into an existing IaC pipeline

If you already have a CI pipeline for your IaC projects, Firefly can seamlessly integrate into it. By choosing this option, Firefly will help you add the necessary steps and configurations to your existing pipeline.

> **Deprecated:** Generate third-party IaC pipeline option is deprecated. This option is no longer available. Please use the Create new IaC pipeline (Firefly Runners) option instead.

### Step 4: General Configuration

Configure your workspace's basic information and organization settings.

**IaC Provisioning Engine** (*Required*): Select the Infrastructure as Code engine your project uses:

* **Terraform**
* **OpenTofu**
* **Terragrunt**

**Name** (*Required*): Choose a clear, descriptive name that identifies your workspace's purpose and environment. Workspace names must be unique within your assigned project. **Description** (*Optional*): Add context about the workspace's purpose, team ownership, or infrastructure it manages. **Labels** (*Optional*): Use labels to categorize and filter workspaces across your organization. **Project Assignment** (*Optional*): Assign this workspace to a project for enhanced organization and access control. If you don't assign a project, the workspace will be accessible to all Firefly users in your organization.

#### Benefits of Project Assignment:

* **Access Control:** Limit workspace access to specific teams or users.
* **Variable Inheritance:** Automatically inherit project-level variables.
* **Resource Organization:** Group related workspaces together.

Click **Next** to proceed to VCS configuration.

### Step 5: VCS Configuration

Connect your workspace to your Version Control System and specify where your infrastructure code is located.

**VCS Integration** (*Required*): Select your Version Control System provider from the available integrations. **Code Repository** (*Required*): Choose the repository containing your Infrastructure as Code files.\
**Default Branch** (*Required*): Select the primary branch where your production-ready infrastructure code resides. This branch will be used for automatic deployments when merging pull requests if configured in the execution settings. **Working Directory** (*Optional*): Specify the directory path within your repository where your root infrastructure module is located. Leave blank if your IaC files are in the repository root. The working directory should contain your root module files (typically `main.tf`, `variables.tf`, and `outputs.tf`).

Click **Next** to configure variables.

### Step 6: Variables Configuration (*Optional*)

Define the variables needed for your infrastructure deployment. Variables can be inherited from variable sets and project variables or defined specifically for this workspace.

**Variable Sets** (*Optional*): Attach existing variable sets to reuse common configurations across multiple workspaces.

#### What are Variable Sets?

* Pre-defined collections of variables that can be shared across workspaces.
* Ideal for common configurations like AWS regions, instance types, or team-specific settings.
* Can include both regular and sensitive variables.

> **Note:** Variable sets are managed separately in Firefly. If you need to create new variable sets, you can do so after workspace creation. Check the [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets) guide for more information.

**Inline Variables** (*Optional*): Define variables specific to this workspace that supplement or override inherited variables.

* **Name:** Variable name.
* **Value:** Variable value.
* **Sensitive:** Mark sensitive values appropriately. If you mark a variable as sensitive, it will be encrypted and hidden from logs and the UI.
* **Environment Variable:** Export as environment variable. If you export a variable as an environment variable, it will be available to your workspace as an environment variable.

#### Injecting a `.tfvars` File at Execution

If you want the workspace to load a specific `.tfvars` file during execution, use Terraform's native `TF_CLI_ARGS_plan` and/or `TF_CLI_ARGS_apply` environment variables. Firefly passes these to Terraform/OpenTofu, which then automatically appends them to the corresponding command.

Use the subcommand-scoped variables (`TF_CLI_ARGS_plan` / `TF_CLI_ARGS_apply`) rather than the global `TF_CLI_ARGS`. The global variable applies to *every* subcommand, including `terraform init`, which has no `-var-file` flag and would fail the run before `plan` even starts.

To set this up, add an inline variable (or a [variable set](/detailed-guides/workflows/creating-variable-sets) variable) with the following configuration:

* **Name:** `TF_CLI_ARGS_plan` and/or `TF_CLI_ARGS_apply`
* **Value:** `-var-file=<name>.tfvars`
* **Environment variable:** The **Environment variable** checkbox **must be checked** — otherwise the value is treated as a regular Terraform variable and the file will not be injected.

| Name                | Value                         | Environment variable |
| ------------------- | ----------------------------- | -------------------- |
| `TF_CLI_ARGS_plan`  | `-var-file=production.tfvars` | ✅ Checked            |
| `TF_CLI_ARGS_apply` | `-var-file=production.tfvars` | ✅ Checked            |

> **Notes:**
>
> * Set `TF_CLI_ARGS_plan` to inject the file during `plan`, and `TF_CLI_ARGS_apply` to inject it during `apply`. In most cases you should set both so the same variables are used across the full run.
> * The `.tfvars` file must exist in the workspace's working directory (it is read from your IaC repository).
> * Replace `<name>.tfvars` with the actual file name, for example `-var-file=production.tfvars`.

> ⚠️ **Don't set `TF_CLI_ARGS_apply` if the workspace runs destroys, or if it uses manual apply on the Terraform (not OpenTofu) engine.** In those cases `apply` runs against a saved plan file, and Terraform rejects `-var-file` with `Error: Can't set variables when applying a saved plan`. Use `TF_CLI_ARGS_plan` alone there — the variables captured during `plan` are already baked into the saved plan. (OpenTofu re-runs `apply` fresh, so setting `TF_CLI_ARGS_apply` is fine on the OpenTofu engine.)

#### Variable Precedence

When variables are defined in multiple places, Firefly follows this precedence order (highest to lowest):

* **Inline Variables** (this workspace)
* **Variable Sets** (attached to workspace)
* **Project Variables** (inherited from project)
* **Organization Variables** (inherited from organization)
* **Default Values** (defined in IaC code)

Click **Next** to configure execution settings.

### Step 7: Execution Configuration

Configure when and how your workspace should execute infrastructure operations.

**Run on Pull Request** (*Recommended*): Enable this option to automatically run `plan` when pull requests are opened against your default branch.

#### Benefits of Run on Pull Request:

* **Early Feedback:** See infrastructure changes before merging.
* **Code Review:** Review `plan` output alongside code changes.
* **Prevent Errors:** Catch issues before they reach production.
* **Compliance:** Ensure changes meet policy requirements.

#### What Happens when Run on Pull Request is enabled:

1. Developer opens a pull request.
2. Firefly automatically triggers a `plan` operation.
3. `plan` results are posted as PR comments.
4. Policy violations are flagged if any exist.
5. Reviewers can see infrastructure impact before approving.

**Run on Merge** (*For Production Workspaces*): Enable this option to automatically run `apply` when pull requests are merged into your default branch.

#### Benefits of Run on Merge:

* **Continuous Deployment:** Immediate infrastructure updates.
* **Consistency:** Ensures every merge results in deployment.
* **Reduced Manual Work:** Eliminates manual deployment steps.
* **Audit Trail:** Complete history of all changes.

#### What Happens when Run on Merge is enabled:

1. Pull request is merged into default branch.
2. Firefly automatically triggers an `apply` operation.
3. Infrastructure is updated according to the merged changes.
4. Notifications are sent to configured channels.

> **Caution:** Only enable auto-apply for well-tested workspaces. Consider manual approval for production environments.

**Path Configurations** (*Optional*): Declare additional file paths — inside or outside the workspace's working directory, and even in other connected repositories — that should trigger a run when modified. Useful for monorepos with shared modules and for workspaces that consume centralized variables or modules from another repository. See [Path Configurations (Change-Based Triggers)](/detailed-guides/workflows/path-configurations) for the full guide.

**Set Periodic Plan** (*Optional*): Enable this option to automatically detect configuration drift and deployment failures.

#### Configuration Options for Set Periodic Plan:

**Simple Scheduling:**

* **Once every X hours:** Enter interval (e.g., 5, 12, 24).
* **Minimum frequency:** Every hour.
* **Common patterns:** Every 6 hours, Daily (24 hours), Twice daily (12 hours).

**Advanced Scheduling:**

* Click the rotation icon to use cron expressions.
* **Examples:**
  * `0 */6 * * *` - Every 6 hours.
  * `0 9 * * 1-5` - Daily at 9 AM, Monday through Friday.
  * `0 2 * * 0` - Weekly on Sunday at 2 AM.

#### Benefits of Set Periodic Plan:

* **Early Detection:** Identify manual changes to your infrastructure or deployment failures.
* **Compliance:** Ensure infrastructure matches your code.
* **Monitoring:** Track deployment health over time.
* **Alerting:** Get notified when drift is detected or deployment fails.

#### Apply Rules

Choose how `apply` operations are handled:

**Manual Apply** (*Recommended for Production*)

* Requires manual approval within Firefly after plan generation.
* Provides an additional safety gate before infrastructure changes.
* Allows for final review of execution plan.
* Ideal for production environments and critical infrastructure.

**Auto Apply** (*For Development/Staging*)

* Automatically applies changes after successful plan.
* Enables fully automated deployment pipeline.
* Suitable for development and staging environments.
* Reduces deployment time and manual intervention.

**Terraform/OpenTofu Version** (*Required*): Select the version of your Infrastructure as Code tool that matches your project requirements.

Click **Next** to complete workspace setup.

### Step 8: Completion

Congratulations! Your Firefly Runners workspace has been successfully created and is ready to manage your infrastructure deployments.

#### What Happens Next

**Immediate Actions:**

1. **Initial State Check:** Firefly automatically runs a baseline `plan` to establish your workspace's initial state.
2. **Configuration Verification:** Review your workspace dashboard to confirm all settings are correct.
3. **Integration Testing:** Your VCS integration is now active and will respond to pull requests and merges.

#### Recommended Next Steps

**1. Test Your Configuration**

* Create a test pull request to verify the PR trigger works.
* Review the generated `plan` output.
* Ensure all variables are correctly configured.

**2. Set Up Notifications**

* Configure notifications to your desired channels.
* Get alerted when plans fail or succeed.
* Keep stakeholders informed of infrastructure changes.

**3. Add Guardrails**

* Implement policy-as-code rules to enforce compliance.
* Set up cost controls and security policies.
* Prevent deployments of resources with no tags.

#### Quick Reference

**Your Workspace Configuration:**

* **Automatic Triggers:** Pull requests and merges will trigger IaC operations.
* **Drift Detection:** Periodic plans will monitor for configuration changes.
* **Security:** Sensitive variables are encrypted and redacted from logs.
* **Audit Trail:** Complete history of all infrastructure changes.

**Common Actions:**

* **Manual Deployment:** Use the *Deploy* button to run IaC operations manually.
* **Edit Variables:** Update workspace variables without recreating the workspace.
* **View Logs:** Access detailed execution logs for troubleshooting.
* **Manage Periodic Plans:** Adjust drift detection frequency as needed.

#### Additional Resources

* [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.
* [Creating Guardrail Rules](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
* [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.
* [SSH Private Module Access](/detailed-guides/workflows/ssh-private-module-access): Configure SSH-based access to private Git repositories for Terraform modules.
* [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.

## Managing Your Firefly Runners Workspace

After creation, you can manage your workspace through various actions:

### Edit Workspace

* Navigate to your workspace, in the actions menu click **Edit**.
* Modify any configuration set during creation.
* Click **Save** to save the changes.

### Edit Variables

* Navigate to your workspace, in the actions menu click **Edit Variables**.
* Attach variable sets or define inline variables specifically for this workspace. These variables will override any inherited ones.
* Click **Save** to save the changes.

### Set Periodic Plan

* Navigate to your workspace, in the actions menu click **Set Periodic Plan**.
* Enable and configure scheduled plan runs to detect infrastructure drift over time.
* Click **Save** to set the time interval for the periodic plan.

### Deploy Workspace

* Navigate to your workspace, in the actions menu click **Deploy**.
* Trigger a `plan` and optionally an `apply` execution for the workspace using your selected branch and settings. You can also add additional CLI arguments for Terraform/OpenTofu/Terragrunt.
* Click **Deploy** to trigger the execution.

### Delete Workspace

* Navigate to your workspace, in the actions menu click **Delete**.
* Permanently delete this workspace from Firefly. You can optionally run a destroy before deletion to clean up infrastructure. This action cannot be undone.
* Click **Delete** to confirm the deletion.

## Best Practices

* **Workspace Organization:** Use descriptive names and labels for easy identification.
* **Variable Management:** Leverage variable sets for consistency across workspaces.
* **Security:** Always use sensitive variables for credentials and secrets.
* **Runner Selection:** Choose managed runners for simplicity, self-hosted for security/compliance requirements.
* **Monitoring:** Enable periodic plans for proactive drift detection and deployment failures.
* **Policy Enforcement:** Implement guardrails to maintain compliance.
* **Documentation:** Maintain clear descriptions and labels for team collaboration.

For hybrid or CI/CD integration, see the [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows) guide. For real-world pipeline examples, visit the [workflows-examples GitHub repository](https://github.com/gofireflyio/workflows-examples).

By following this guide, you can effectively create and manage Firefly Runners workflows, providing a fully integrated, scalable, and secure infrastructure automation experience.


# Path Configurations (Change-Based Triggers)

> **Related Guides:**
>
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to create a workspace and set the working directory.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): Manually triggering a deployment from the UI.
> * [Creating Guardrail Rules](/detailed-guides/workflows/creating-guardrail-rules): Policy enforcement applied to runs created by any trigger.

Every Firefly workspace is associated with a code repository and an optional **working directory** — the path within the repository where the workspace's IaC configuration lives. By default, a workspace runs only when files inside its working directory change.

**Path Configurations** extend that behavior by letting a workspace declare interest in additional file paths — including paths in *different* repositories. When a push modifies any matching file, Firefly triggers a run on the workspace, even if no file inside the workspace's own working directory changed.

This is especially useful for:

* **Monorepos**, where a single repository hosts many workspaces alongside shared Terraform modules and variable files.
* **Cross-repository module dependencies**, where a workspace consumes modules or configuration that live in a different repository entirely.
* **Centralized configuration**, where files such as `global.tfvars`, organization tag defaults, or compliance policies are maintained in one place and consumed by many workspaces.

## How Path Configurations Work

A workspace evaluates two sources of trigger paths on every incoming VCS push event:

1. **Working directory** — the workspace's own root module path, set when the workspace is created. Any change to a file under this path triggers a run on the workspace.
2. **Path configurations** — one or more additional `{repository, path}` entries declared on the workspace. Any push that modifies a file matched by an entry triggers a run on the workspace.

A match against **either** the working directory or any single path configuration is sufficient to trigger the run. Path configurations are **trigger-only**: when a run is triggered, the runner still executes from the workspace's working directory in the workspace's own repository. The matched paths are only used to decide *whether* to trigger; they do not change *what* is executed.

### Run Type by Event

| VCS event                                                 | Working directory match                       | Path configuration match                       |
| --------------------------------------------------------- | --------------------------------------------- | ---------------------------------------------- |
| Push to the workspace's tracked branch                    | Tracked run (plan and, optionally, apply)     | Tracked run (plan and, optionally, apply)      |
| Pull request opened or updated against the tracked branch | Proposed run (plan only — never auto-applies) | **No run** — path configurations are push-only |
| Push to any other branch                                  | No run                                        | No run                                         |

Path configurations fire on **push events only**. A pull request that changes a path matched by a path configuration does not create a run — this keeps proposed-run noise out of dependent workspaces and reserves PR-time plans for the workspace whose own working directory is being edited. To get plan feedback on a pull request that touches a shared module, work through the workspace that owns that module's working directory (or open the PR against that workspace's repository directly).

A path configuration does not change *how* a run applies. Whether a path-triggered run auto-applies or waits for manual approval is governed by the workspace's existing **Auto Apply** / **Manual Apply** setting, exactly as for a working-directory-driven run. A path configuration only broadens the set of file paths that count as a "change to this workspace" on a push.

### Cross-Repository Triggers

When a path configuration points at a repository other than the workspace's own (a **cross-repository** entry), the trigger is still scoped to the workspace's own repository:

* The run executes against the workspace's **own repository** at the workspace's **default branch** — never the source repository or the source push's branch. The cross-repository entry acts purely as a trigger.
* Downstream check-run and PR-comment dispatch target the workspace's own repository, using the workspace's VCS integration credentials.
* The run's **Triggered By** card identifies the cross-repository entry that fired the trigger, so you can trace the run back to its source push.

This means a single push to a shared-module repository can fan out to many tracked-branch runs across many workspaces in many other repositories — each running its own `plan` (and optionally `apply`) from its own working directory.

## When to Use a Path Configuration

Use a path configuration when changes to files *outside* a workspace's working directory should still trigger a run on that workspace.

**Common scenarios:**

* The workspace consumes a shared Terraform module from another folder in the same repository (e.g., `modules/shared-vpc/`), and you want to re-plan the workspace whenever that module changes.
* The workspace reads from a centralized variables file (e.g., `config/global-settings.tfvars`) maintained outside the working directory.
* The workspace consumes a module hosted in a *different* repository entirely.
* You want a single change in a foundational file to trigger plans across many workspaces in a monorepo.

**When&#x20;*****not*****&#x20;to use a path configuration:**

* The path you want to watch is the working directory of *another* workspace in the same account. In that case, the right tool is a **workspace dependency** — Firefly will refuse to register a path configuration that overlaps another workspace's working directory and will direct you to use a dependency instead.
* You want to trigger the entire repository on every commit. Path configurations cannot point to the repository root.
* You want pull-request-time feedback on the path. Path configurations do not fire on PR events.

## Path Pattern Syntax

A path configuration entry consists of:

* **VCS Repository** — the repository to watch. This can be the workspace's own repository or any other repository connected to your Firefly account through a VCS integration. The repository is identified by `<integration-id>:<owner/repo-name>`, so repositories with the same `owner/repo-name` reached through different VCS integrations remain distinct.
* **Path Pattern** — a single path within that repository.
* **Execution Type** — what to run when this entry matches (see [Execution Type per Entry](#execution-type-per-entry)).

Three pattern forms are supported:

| Pattern form           | Example                         | Matches                                                                                                                  |
| ---------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Directory prefix**   | `modules/shared-vpc`            | Any file at any depth under `modules/shared-vpc/` (e.g., `modules/shared-vpc/main.tf`, `modules/shared-vpc/nested/x.tf`) |
| **Exact file**         | `config/global-settings.tfvars` | Exactly that file path                                                                                                   |
| **Recursive wildcard** | `modules/**`                    | Any file at any depth under `modules/`                                                                                   |

Paths are relative to the repository root. A leading `/` is accepted but optional — `modules/shared-vpc` and `/modules/shared-vpc` are equivalent.

### Pattern Rules

* **Single-star wildcards are not supported.** A pattern containing a bare `*` (for example `config/*.tfvars`) is rejected. Use `**` for recursive matching, or specify a directory prefix.
* **Repository-root patterns are not allowed.** The values `""`, `"/"`, and `"**"` are rejected because they would match every file in the repository — equivalent to setting the workspace's working directory to the repository root. Path configurations must always point to a specific subdirectory, file, or sub-tree.
* **Multiple entries are supported.** A workspace can declare multiple path configuration entries; a match on **any** single entry triggers the run.
* **Pattern matching is precise.** The matcher honors the literal pattern, including underscores and percent signs — those are *not* treated as wildcards.

## Configuring Path Configurations from the UI

Path configurations are managed on the workspace itself, alongside the other trigger and execution settings.

### Step 1: Open the Workspace Trigger Settings

Navigate to **Workflows → Workspaces**, open the workspace, and click **Edit**. Path configurations appear under the workspace's trigger configuration.

### Step 2: Add a Path Configuration Entry

Click **Add Path Configuration** and provide the three fields:

* **VCS Repository** — pick a repository from the account's connected VCS integrations. The picker shows the integration name alongside the repository slug (e.g., `Github : org/infra-modules`) so repositories with the same `owner/repo-name` accessed through different integrations remain distinct.
* **Path Pattern** — enter a directory prefix, exact file, or recursive wildcard pattern. Inline validation flags the entry the moment it would be rejected on save (e.g., a single-star wildcard, an empty path, or a path that conflicts with another workspace's working directory).
* **Execution Type** — choose **Plan** or **Plan and Apply**.

You can add additional entries the same way, up to a maximum of **2** entries per workspace.

### Step 3: Save

Click **Save**. Validation runs at submit time as well — if any entry is invalid, the entire save is rejected and the offending entry is highlighted.

To remove an entry, open the workspace edit form and click the **delete** icon next to the entry. To edit an entry, change its fields and save.

## Execution Type per Entry

Each path configuration entry declares its own **Execution Type**, which controls what happens when *that specific entry* matches a changed file on a push:

| Execution Type     | Behavior on tracked run                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| **Plan**           | The workspace runs `plan` only. The run never enters `apply`, regardless of the workspace's auto-apply setting. |
| **Plan and Apply** | The workspace follows the workspace's standard apply policy: auto-apply if enabled, manual approval if not.     |

Use `plan` for change-detection on files where an automatic apply would be undesirable (for example, a shared variables file that several teams modify), and `plan_and_apply` for paths whose changes should follow your normal deployment cadence.

### Multiple Matches in the Same Run

If a single commit modifies files matched by **more than one** path configuration entry on the same workspace, only one run is created and the **most permissive** execution type wins: `plan_and_apply` overrides `plan`. To enforce stricter behavior for a particular path, split the work across two workspaces with non-overlapping entries.

### Approval Gating

Whether a `plan_and_apply` run requires manual approval before applying is governed by the **workspace-level** apply rule:

* Workspaces with **Auto Apply** enabled apply automatically after a successful plan.
* Workspaces with **Manual Apply** require an explicit approval before `apply` proceeds.

Approval gating is intentionally a property of the workspace as a whole, not a per-entry setting. This keeps the workspace's run history coherent — every run on the workspace follows the same approval policy.

## Validation and Conflicts

Path configurations are validated both as you type in the UI (inline feedback) and again on save. The same rules apply via the API.

| Rule                                                                        | Result if violated                                                                                                                                                                                                                                     |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Path is empty, missing, or contains only `/` or `**`                        | Rejected — a path configuration must point to a specific subdirectory, file, or sub-tree (not the repository root).                                                                                                                                    |
| Pattern contains a single-star (`*`) wildcard                               | Rejected — only `**` recursive wildcards and directory/file paths are supported.                                                                                                                                                                       |
| VCS repository is not connected to the account                              | Rejected — the selected repository must belong to a VCS integration the account can access.                                                                                                                                                            |
| Path matches the working directory of another workspace in the same account | Rejected — Firefly suggests using a [workspace dependency](/detailed-guides/workflows/creating-workflows) instead, since a change to a path that *is* another workspace's root is more naturally expressed as "trigger that workspace, then this one". |
| Duplicate `{repository, path}` entries within the same workspace            | Deduplicated automatically.                                                                                                                                                                                                                            |

When the validator rejects an entry, the message identifies the offending field and, where relevant, the conflicting workspace by name so you can navigate directly to it.

## The "Triggered By" Run Card

Runs that fire because of a path configuration show a **Triggered By** summary in the run's details, so you can see at a glance *why* a given run was created. The summary captures:

* **Trigger type** — `path-config` for runs triggered by a path configuration entry; `push` or `pull-request` for runs triggered by the workspace's own working directory.
* **Triggered at** — the timestamp at which the trigger was evaluated and the run created.
* **Matched entries** — the `{repository, path}` entries that drove the trigger. When more than one entry matched in the same commit, all of them appear.

This makes it easy to trace a cross-repository run back to the upstream change that caused it. Runs triggered by changes to the workspace's own working directory show the `push` or `pull-request` trigger type with no matched entries.

## Multi-Workspace Behavior

In a monorepo (or across many repositories) a single push can match the working directories or path configurations of several workspaces simultaneously. In that case Firefly creates one run per matching workspace, and runs that are independent of each other execute in parallel on the assigned runner pool.

## VCS Provider Support

Path configurations work transparently with all supported VCS integrations:

* GitHub (and GitHub Enterprise)
* GitLab
* Bitbucket
* Azure DevOps

This includes **cross-VCS** triggers — a workspace on GitHub can declare a path configuration against a GitLab repository, and a push on the GitLab side triggers a run on the GitHub workspace using the GitHub integration's credentials. No VCS-specific configuration is required — webhook delivery, push detection, and commit-status reporting all behave the same as for working-directory-triggered runs. See [Integrating Version Control](/integrations/version-control) for integration setup.

## Examples

### Example 1: Shared Module in a Monorepo

A workspace `prod-networking` lives at `terraform/prod/networking/` and consumes a module at `modules/shared-vpc/` in the same repository.

| Field                                  | Value                                       |
| -------------------------------------- | ------------------------------------------- |
| Working Directory                      | `terraform/prod/networking`                 |
| Path Configuration #1 — Repository     | `org/prod` (the workspace's own repository) |
| Path Configuration #1 — Path           | `modules/shared-vpc`                        |
| Path Configuration #1 — Execution Type | `plan_and_apply`                            |

A push that modifies `terraform/prod/networking/main.tf` triggers a run because of the working directory. A push that modifies `modules/shared-vpc/main.tf` also triggers a run, because of the path configuration. A pull request that modifies `modules/shared-vpc/main.tf` does **not** trigger `prod-networking` — to get PR-time feedback on the shared module, work through whichever workspace owns `modules/shared-vpc` as its working directory.

### Example 2: Cross-Repository Module Consumer

The same `prod-networking` workspace also consumes a module from a different repository, `org/infra-modules`, on the same VCS integration.

| Field                                  | Value                       |
| -------------------------------------- | --------------------------- |
| Working Directory                      | `terraform/prod/networking` |
| Path Configuration #1 — Repository     | `org/prod`                  |
| Path Configuration #1 — Path           | `modules/shared-vpc`        |
| Path Configuration #1 — Execution Type | `plan_and_apply`            |
| Path Configuration #2 — Repository     | `org/infra-modules`         |
| Path Configuration #2 — Path           | `modules/shared-vpc/**`     |
| Path Configuration #2 — Execution Type | `plan_and_apply`            |

A push to either repository now triggers `prod-networking`. The runner still clones `org/prod` at `prod-networking`'s default branch — the cross-repository entry only acts as a trigger, never as a source for the clone.

### Example 3: Plan-Only Watch on a Variables File

The workspace watches a centralized variables file, but you want a human to review any change before applying.

| Field                               | Value                    |
| ----------------------------------- | ------------------------ |
| Path Configuration — Repository     | `org/platform-config`    |
| Path Configuration — Path           | `defaults/global.tfvars` |
| Path Configuration — Execution Type | `plan`                   |

A push that changes `defaults/global.tfvars` triggers a `plan`-only run on the workspace. The workspace's own `apply` cadence is unaffected — `apply` still runs on changes to the working directory or to entries declared with `plan_and_apply`.

## Limitations

* A workspace can have up to **2** path configuration entries.
* Path configurations are **push-only**. Pull-request events on a path-configuration-matched file do not create runs.
* Path configurations are **trigger-only**. They do not modify the working directory, alter what files the runner sees, or pass values into the run.
* Cross-repository runs always clone the **workspace's own repository at its default branch** — there is no option to clone the source repository, and the source push's branch is not used.
* Patterns must point to a path below the repository root. To trigger on every change in a repository, set the workspace's working directory to the repository root instead.
* Single-star (`*`) wildcards are not supported in MVP. Use `**` for recursive matching or a directory/file path.

## Related Guides

* [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows) — Workspace creation, working directory, and trigger basics.
* [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy) — Manually triggering a workspace from the UI.
* [Integrating Version Control](/integrations/version-control) — Connecting a VCS provider so push events reach Firefly.
* [Creating Guardrail Rules](/detailed-guides/workflows/creating-guardrail-rules) — Policies evaluated on every run, including those triggered by path configurations.


# Creating Guardrail Rules

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
> * [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.
> * [Wiz Policy Integration](/detailed-guides/workflows/wiz-policy-integration): Delegating IaC policy evaluation to Wiz instead of Firefly's built-in policy engine.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.
> * [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows): For hybrid or external CI/CD integration.
> * [Firefly Workflows Example Pipelines](https://github.com/gofireflyio/workflows-examples): Real-world pipeline and integration templates for Jenkins, GitHub Actions, and more.

Firefly Guardrails are a powerful feature for enforcing policies and best practices within your Infrastructure as Code (IaC) workspaces. By establishing specific rules, Guardrails ensure your Terraform, OpenTofu, and Terragrunt deployments adhere to organizational standards, preventing non-compliant changes from being applied. Guardrails can block deployments that violate these rules, thereby maintaining the integrity, security, cost-efficiency, and compliance of your cloud infrastructure.

This document provides a comprehensive guide on how to create and configure Guardrail rules in Firefly.

## Introduction to Guardrails

Guardrails act as automated checks and balances for your IaC deployments. They provide a way to codify your organization's governance policies and apply them consistently across your workspaces.

**Key Benefits of Using Guardrails:**

* **Policy Enforcement:** Ensure that all deployments comply with security policies, cost management strategies, tagging standards, and resource configuration best practices.
* **Risk Reduction:** Prevent accidental or malicious changes that could lead to security vulnerabilities, cost overruns, or operational instability.
* **Compliance:** Help meet internal and external regulatory compliance requirements by enforcing specific configurations.
* **Consistency:** Maintain a consistent and standardized cloud environment across all projects and teams.
* **Automated Prevention:** Block non-compliant deployments *before* they are applied, saving time and resources on remediation.
* **Comprehensive Coverage:** Optionally evaluate existing resources that aren't being modified (no-op assets) in addition to new or changed resources, ensuring all infrastructure gets checked for policy and tag compliance.

## Guardrail Rule Types

Firefly offers several types of rules to enforce various policies in your Workspaces. Understanding these types is key to creating effective Guardrails:

1. **Cost Rules:**
   * **Function:** Manage and control cloud costs by setting limits on estimated cost changes resulting from a `terraform plan`, `tofu plan`, or `terragrunt plan`.
   * **Use Case:** Monitor potential cost increases or decreases and block deployments that exceed a specified monetary amount or percentage threshold.
   * *Example:* A Cost rule can be set to block any deployment that results in an estimated cost increase of more than $100 or 10% of the current cost.
2. **Policy Rules:**
   * **Function:** Ensure adherence to predefined security, compliance, or operational best practices. These rules leverage a policy engine (Open Policy Agent - OPA) to evaluate the planned changes.
   * **Use Case:** Verify that planned resources meet specific criteria (e.g., encryption enabled, public access restricted, specific instance types used/disallowed). Prevent deployments that violate these organizational standards.
   * **No-Op Assets Evaluation:** Policy rules can optionally evaluate existing resources in your plan that aren't being created, modified, or deleted, ensuring comprehensive compliance checking across all infrastructure.
   * *Example:* A Policy rule can ensure that all new S3 buckets have server-side encryption enabled. If a deployment attempts to create an S3 bucket without encryption, the Guardrail blocks it. With no-op evaluation enabled, it can also check that existing S3 buckets in the plan maintain encryption compliance.
3. **Resource Rules:**
   * **Function:** Control modifications (create, update, delete, import) to cloud resources based on their type, region, specific address (identifier), or other attributes.
   * **Use Case:** Block specific actions on certain resources to enforce architectural standards, regional policies, or prevent accidental deletion of critical infrastructure.
   * *Example:* A Resource rule can prevent the creation of new resources in a restricted region (e.g., `us-west-2`) or block the deletion of a critical database instance.
4. **Tag Rules:**
   * **Function:** Enforce consistent tagging standards across all your resources. Ensure that resources have required tags, specific tag names, and/or approved tag values.
   * **Use Case:** Improve resource management, cost allocation, and automation by ensuring all deployed resources are correctly tagged according to organizational policies.
   * **No-Op Assets Evaluation:** Tag rules can optionally evaluate existing resources in your plan that aren't being created, modified, or deleted, ensuring comprehensive tagging compliance across all infrastructure.
   * *Example:* A Tag rule can block any deployment where resources are missing a mandatory `Environment` tag or if the `CostCenter` tag uses a value not in an approved list. With no-op evaluation enabled, it can also verify that existing resources in the plan maintain proper tagging standards.

*Note: Workspaces with the* [*Wiz Policy Integration*](/detailed-guides/workflows/wiz-policy-integration) *enabled behave differently. Firefly's built-in policy scans are skipped for those workspaces, because Wiz becomes the policy authority. Your own custom policies still run and are reported, but they only block a run when their Violation Behavior is set to **Strict Block**.*

## Creating a New Guardrail Rule: Step-by-Step

Follow the wizard in the Firefly UI to create a new Guardrail rule.

**Procedure:**

1. **Navigate to Guardrails:**
   * In the Firefly UI, click on **Workflows** from the main navigation menu.
   * Then, click on the **Guardrails** tab or sub-section.
2. **Add New Guardrail Rule:**
   * Click on the **+ Add New Guardrail** button.
3. **Select the Rule Type:**
   * Choose one of the available rule types based on the policy you want to enforce:
     * **Cost**
     * **Policy**
     * **Resource**
     * **Tag**
   * The subsequent configuration options will vary based on the selected rule type.
4. **Enter Rule Name:**
   * Provide a clear, descriptive name for your Guardrail rule.
   * *Example:* `Block High Cost Increases`, `Enforce S3 Encryption`, `Prevent us-west-2 Deployments`, `Require Environment Tag`.
5. **Configure Violation Behavior:** Choose how Firefly should behave when this Guardrail rule is violated:
   * **Strict Block:**
     * Prevents any override of the violation.
     * If this rule is violated, the deployment is definitively blocked, and cannot proceed unless the underlying IaC or the rule itself is changed to resolve the violation.
     * Use for critical policies where no exceptions are allowed.
   * **Flexible Block:**
     * Blocks the deployment by default but allows authorized users (with appropriate permissions in Firefly) to override the violation.
     * This provides a balance between enforcement and operational flexibility for exceptional cases.
     * Overrides can be one-time (for the current run only) or permanent (exempting the specific violation instance from future checks for this rule until revoked).
6. **Define the Scope of Your Guardrail:** Specify which Workspaces, Repositories, Branches, and Labels this Guardrail rule should apply to. This allows for granular control over where your policies are enforced.

   * **Workspaces:**
     * Enter specific Workspace names or patterns.
     * Use wildcards (`*`) to match multiple Workspaces (e.g., `prod-*`, `*-database`).
     * Leave blank to apply to all Workspaces by default (within the further constraints of Repository, Branch, etc.).
   * **Repositories:**
     * Enter specific repository names or patterns (e.g., `org/app-*`, `*/*-infra`).
     * Use wildcards (`*`) for matching.
     * Leave blank to apply to all repositories associated with the selected Workspaces.
   * **Branches:**
     * Enter specific branch names or patterns (e.g., `main`, `features/*`, `release-*`).
     * Use wildcards (`*`).
     * Leave blank to apply to all branches within the selected repositories/workspaces.
   * **Labels:**
     * Filter by Workspace labels.
     * Specify labels that Workspaces must have for this rule to apply (e.g., `production`, `staging`).

   *Note: The scope acts as a set of AND conditions. A deployment must match all specified scope criteria for the Guardrail rule to be evaluated against it.* If a field is left blank, it means *applies to all* for that specific dimension of the scope.
7. **Define Rule-Specific Criteria:** The options here depend on the **Rule Type** selected in Step 3.
   * **For Cost Rules:**
     * **Trigger Condition:** Specify the cost change threshold that, if exceeded, triggers this Guardrail.
       * Choose between an **Exact Amount** (e.g., $100) or a **Percentage** (e.g., 10%).
     * **Amount/Percentage Value:** Define the actual limit.
       * *Example (Amount):* `100` (meaning if cost change > $100, block).
       * *Example (Percentage):* `10` (meaning if cost change > 10%, block).
     * You can specify negative values to allow enforcement of cost decreases.
   * **For Policy Rules:**
     * **Select Policies to Apply:**
       * Choose one or more specific policies from Firefly's policy library (these could be built-in policies or custom policies your organization has defined).
       * Leave blank to apply to *all* relevant policies (less common, you should select specific policies to avoid unintended blocks).
     * **Policies to Exclude (Optional):**
       * Select any policies that should be explicitly excluded from this Guardrail rule, even if they match the selection criteria above.
     * **Minimum Severity Level:**
       * Select the minimum severity level (e.g., `High`, `Medium`, `Low`) of policy violation that this Guardrail should enforce.
       * For example, if set to `Medium`, the Guardrail will only block for policy violations flagged as `High` or `Medium`.
     * **Include No-Op Assets (Optional):**
       * Enable this option to evaluate existing resources in your plan that aren't being created, modified, or deleted.
       * When enabled, the Guardrail will check all infrastructure resources for policy compliance, not just new or changed ones.
       * This provides comprehensive coverage but may identify violations in existing resources that weren't previously checked.
   * **For Resource Rules:** This rule type allows you to block specific actions (create, update, delete, import) based on resource attributes.
     * **Actions to Block:** Select the actions you want to restrict (e.g., check `Create`, `Delete`).
     * **Asset Types:**
       * Specify the Terraform/OpenTofu resource types this rule applies to (e.g., `aws_s3_bucket`, `google_compute_instance`, `azurerm_virtual_machine`).
       * Use wildcards if you want to match multiple resource types (e.g., `aws_db_*`).
       * Leave blank to apply to all resource types (use with caution).
     * **Exclude Asset Types:**
       * Select any asset types that should be explicitly excluded from this Guardrail rule, even if they match the selection criteria above.
     * **Regions:**
       * Specify cloud provider regions where these actions on these asset types should be blocked (e.g., `us-west-2`, `eu-central-1`).
     * **Exclude Regions:**
       * Select any regions that should be explicitly excluded from this Guardrail rule, even if they match the selection criteria above.
     * **Resource Addresses (Specific Identifiers):**
       * Specify particular resource addresses or patterns to target specific instances (e.g., `aws_instance.my_critical_server`, `module.vpc.aws_nat_gateway.this`).
     * You can combine these conditions (e.g., block `Delete` action for `aws_db_instance` resources in the `eu-west-1` region whose names match `prod-*`).
   * **For Tag Rules:**
     * **Tag Enforcement Type:**
       * **Block if Missing Any Tags (Tag Missing Entirely):** The deployment is blocked if any resource in the plan is missing *any* tags at all.
       * **Block if Specific Tag Name Missing:** The deployment is blocked if resources are missing one or more *specified* tag keys.
       * **Block if Specific Tag Value Invalid:** Block if a specific tag key has a value that is not in an approved list.
     * **Required Tag Keys (if "Specific Tag Missing" selected):**
       * Specify the list of tag keys that must be present on resources.
       * *Example:* `Environment`, `CostCenter`, `Owner`.
       * Use wildcards (`*`) for tag key patterns.
     * **Allowed Tag Values (if "Specific Tag Value Invalid" selected):**
       * Specify the list of tag names and values that must be present on resources.
       * *Example:* `Environment` key with values `production`, `staging`, `dev`, `CostCenter` key with values `finance`, `marketing`.
       * Use wildcards (`*`) for tag value patterns.
     * **Include No-Op Assets (Optional):**
       * Enable this option to evaluate existing resources in your plan that aren't being created, modified, or deleted.
       * When enabled, the Guardrail will check all infrastructure resources for tagging compliance, not just new or changed ones.
       * This ensures comprehensive tagging standards across your entire infrastructure state.
8. **Configure Notifications (Optional):** Set up notifications to alert relevant teams or individuals when this Guardrail rule is violated or overridden.
   * **Select Notification Destination(s):**
     * Choose from available notification destinations configured in Firefly (e.g., Slack, Email, PagerDuty, Webhooks).
   * The system will automatically send alerts to the specified destinations, ensuring timely visibility into policy enforcement actions.
9. **Review and Save:**
   * Carefully review all the configured settings for your Guardrail rule.
   * Ensure the scope, criteria, and violation behavior are correctly defined to achieve your intended policy enforcement.
   * Click **Create** to create and activate the Guardrail rule.

## After Creating a Guardrail Rule

* **Activation:** The rule becomes active immediately or as per its configuration and will be evaluated against new `terraform plan`, `tofu plan`, or `terragrunt plan` operations that fall within its defined scope.
* **Evaluation:** When a `terraform plan`, `tofu plan`, or `terragrunt plan` is executed for a Workspace covered by the Guardrail rule:
  1. Firefly analyzes the plan output.
  2. It checks if the planned changes violate any criteria of applicable Guardrail rules.
  3. For Policy and Tag rules with no-op assets evaluation enabled, it also checks existing resources in the plan that aren't being modified.
* **Guardrails Step in Workflow:** If a deployment violates one or more Guardrails:
  * The deployment process in Firefly pauses at a *Guardrails Step*.
  * Firefly displays the specific violations, details of the rules that were checked (both passed and failed), and provides feedback or remediation guidance.
  * AI-Generated Remediation: Look for a *Tinkerbell* icon next to violation messages. Clicking this provide AI-generated suggestions, explanations, and proposed code changes to fix the violation.
* **Pull Request (PR) Comment:** If the deployment is associated with a PR, Firefly posts a comment to the PR detailing all Guardrail violations. This informs the development team directly within their VCS workflow.
* **Overrides (for Flexible Block):** If the rule's violation behavior is set to *Flexible Block* and a violation occurs:
  * Authorized users will see an option to **Override** the violation within the Guardrails Step in Firefly.
  * **Override Types:**
    * **One-time Override:** Grants an exception for the current pipeline run only. The violation will still be enforced in future deployments unless overridden again. This is a one-time override.
    * **Permanent Override:** Exempts this specific instance of the violation from this rule in future deployments. The exception remains unless manually revoked.
  * After applying an override, users can choose to **Rerun Pipeline** to continue the deployment.
* **Tracking Overrides:** Overridden violations are tracked and visible in:
  * The Guardrails Step for the specific run.
  * PR comments (if applicable).
  * A dedicated section in the Workspace menu under *View Overridden Violations* where permanent overrides can be reviewed and revoked.
  * Notifications are sent for override actions if configured.

## Managing Guardrail Rules

Once created, you can manage your Guardrail rules:

* **Viewing and Filtering:** The Guardrails page lists all configured rules. You can use filters to find specific rules based on:
  * **Text Search:** Search by rule name or keywords.
  * **Creator:** Filter by the user who created the rule.
  * **Type:** Filter by rule type (Policy, Cost, Resource, Tag).
  * **Scope:** Filter by Labels, Repositories, or Workspaces the rules apply to.
* **Editing:** Modify existing rules (name, scope, criteria, behavior, notifications).
* **Deleting:** Remove rules that are no longer needed.
* **Disabling/Enabling:** Temporarily disable a rule without deleting it.

## Examples of Guardrail Rules

Here are some practical examples based on the rule types:

* **Policy Rule Example:**
  * **Rule Name:** `Enforce Encryption on All S3 Buckets`
  * **Rule Type:** Policy
  * **Violation Behavior:** Strict Block
  * **Scope:** All Workspaces (`*`)
  * **Criteria:**
    * Select Policy: `S3 Buckets Must Have Server-Side Encryption Enabled` (assuming this is a predefined policy in Firefly)
    * Minimum Severity: `High`
* **Resource Rule Example:**
  * **Rule Name:** `Disallow Resource Creation in us-west-2`
  * **Rule Type:** Resource
  * **Violation Behavior:** Flexible Block
  * **Scope:** All Workspaces (`*`) except a specific development Workspace (e.g., by explicitly excluding it or using label-based scope like `env:!dev`)
  * **Criteria:**
    * Actions to Block: `Create`
    * Asset Types: `*` (all resource types)
    * Regions: `us-west-2`
* **Tag Rule Example:**
  * **Rule Name:** `Ensure Environment Tag on All Compute Instances`
  * **Rule Type:** Tag
  * **Violation Behavior:** Strict Block
  * **Scope:** Workspaces with label `project:critical-apps`
  * **Criteria:**
    * Tag Enforcement Type: `Block if Specific Tag Name Missing`
    * Required Tag Keys: `Environment`
    * (Further criteria could be added to apply this only to compute instance resource types if the Resource Rule criteria can be combined or if Tag rules have Asset Type scope).
* **Cost Rule Example:**
  * **Rule Name:** `Limit Development Cost Increases to $50`
  * **Rule Type:** Cost
  * **Violation Behavior:** Flexible Block
  * **Scope:** Workspaces with label `env:development`
  * **Criteria:**
    * Trigger Condition: Exact Amount
    * Amount Value: `50` (USD)
    * Applies to: Cost Increases

## Best Practices for Creating Guardrails

* **Start Small and Iterate:** Begin with a few critical Guardrails and gradually expand your rule set as your organization's needs evolve and mature.
* **Be Specific with Scope:** Clearly define the scope of each Guardrail to avoid unintended consequences. Use labels and patterns effectively.
* **Use Flexible Block Wisely:** While Flexible Block provides operational leeway, ensure that overrides are properly governed and reviewed.
* **Clear Naming Conventions:** Use descriptive names for your Guardrail rules so their purpose is easily understood.
* **Regularly Review and Update:** Policies and infrastructure change. Periodically review your Guardrail rules to ensure they are still relevant and effective.
* **Involve Stakeholders:** Collaborate with security, finance, and operations teams when defining Guardrail rules to ensure they align with overall business objectives.
* **Document Your Guardrails:** Maintain internal documentation explaining the purpose and rationale behind each Guardrail rule.

By thoughtfully creating and managing Guardrail rules, you can significantly enhance the security, compliance, and operational stability of your cloud infrastructure deployed via Firefly Workflows.


# Wiz Policy Integration

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce Firefly's own policies and best practices.
> * [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections, including the `Wiz Policy Integration Authentication` template.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows): Setting up `fireflyci` in your own pipeline.

Firefly can delegate Infrastructure-as-Code policy evaluation to [Wiz](https://www.wiz.io/). When a workspace resolves Wiz credentials, its runs are scanned by Wiz instead of by Firefly's built-in policy engine, and the run is blocked if Wiz returns a failing verdict.

This is intended for organizations that already treat Wiz as the authority for cloud security policy and want the same policies enforced at the IaC level, before infrastructure is applied — without maintaining a parallel policy set in Firefly.

Wiz remains the policy authority throughout. Firefly does not interpret Wiz rules, choose which Wiz policies run, or remap Wiz verdicts into its own vocabulary. It runs the scan, presents the result verbatim, and enforces the outcome.

## How It Works

For a Wiz-integrated workspace, a run proceeds through the following stages:

1. **Checking Integrations:** Before `init`, Firefly validates the Wiz connection using the resolved credentials. The run displays a dedicated **Checking Integrations** status while this happens. If validation fails, the run stops with **Init Failed**.
2. **Init and Plan:** `terraform init` and `terraform plan` (or the OpenTofu/Terragrunt equivalents) run as usual.
3. **Wiz Scan:** After `plan`, the plan is exported to JSON and scanned by Wiz. The scan is plan-aware — Wiz evaluates the changes the plan will make, not just the static configuration.
4. **Guardrails Step:** Wiz results are displayed alongside any Firefly custom policy results.
5. **Gate:** If Wiz returns a failing verdict, the run is blocked before `apply`. Otherwise it proceeds to `apply` (or awaits approval, per your existing workflow configuration).

### What Changes for an Integrated Workspace

| Scan type                     | Behavior                                                                                                |
| ----------------------------- | ------------------------------------------------------------------------------------------------------- |
| Wiz scan                      | **Runs.** Blocking on the Wiz verdict.                                                                  |
| Firefly built-in policy scans | **Skipped.** Wiz is the policy authority.                                                               |
| Kicks scans                   | **Skipped.**                                                                                            |
| Firefly custom policy scans   | **Runs.** Reported but non-blocking, unless the policy's Violation Behavior is set to **Strict Block**. |

Workspaces that do not resolve Wiz credentials are entirely unaffected — kicks and built-in policy scans run exactly as before.

### Execution Models

The integration supports two execution models. Both use the same Wiz scan output, the same blocking rules, and the same UI. They differ in who runs the Wiz CLI:

* **Firefly-managed workspaces.** Firefly provisions the Wiz CLI, authenticates, runs the scan, and enforces the gate. See [Setting Up for Firefly-Managed Workspaces](#setting-up-for-firefly-managed-workspaces).
* **Your existing CI/CD pipeline.** Your pipeline owns and runs the Wiz CLI, then hands the scan result to Firefly through `fireflyci`. See [Setting Up in an Existing CI/CD Pipeline](#setting-up-in-an-existing-cicd-pipeline).

## Prerequisites

* **A Wiz tenant** with IaC scanning enabled.
* **A Wiz OAuth2 service account.** Create a service account in the Wiz portal and record its **Client ID** and **Client Secret**. The service account only needs **read-only** permissions — it scans, it does not modify your Wiz tenant.
* **Network egress to Wiz.** Whatever environment runs the scan needs outbound HTTPS access to the Wiz authentication and API hosts (`auth.app.wiz.io` and `api.*.wiz.io`, or their GovCloud/FedRAMP equivalents). For Firefly-managed runs this applies to Firefly's runners; if you use a [self-hosted runner pool](/detailed-guides/workflows/creating-self-hosted-runner), ensure your network policy allows it.
* **Linux amd64 or arm64 runners.** The Wiz CLI is distributed only as a Linux amd64/arm64 binary. This constrains self-hosted runner pools used for Wiz-integrated workspaces, and your CI/CD job images in the pipeline model.

## Setting Up for Firefly-Managed Workspaces

Wiz is enabled through a variable set. There is **no separate enable toggle** — a workspace becomes Wiz-integrated as soon as `WIZ_CLIENT_ID` and `WIZ_CLIENT_SECRET` resolve for it, whether directly or through inheritance.

### Step 1: Create the Variable Set

1. In the Firefly UI, navigate to **Workflows > Projects & Variables**.
2. Click **+ Create new variable set**.
3. Select the **`Wiz Policy Integration Authentication`** template. This pre-populates the set with the three Wiz variables.
4. Give the set a name and, optionally, assign it to specific projects to control which workspaces can consume it.
5. Fill in the variable values:

| Variable            | Description                                                                                                      | Required |
| ------------------- | ---------------------------------------------------------------------------------------------------------------- | -------- |
| `WIZ_CLIENT_ID`     | The OAuth2 service account client ID from the Wiz portal.                                                        | Yes      |
| `WIZ_CLIENT_SECRET` | The OAuth2 service account client secret. Must be marked **Sensitive**.                                          | Yes      |
| `WIZ_ENV`           | Set to `gov` for Wiz GovCloud (`gov.wiz.io`) or `fedramp` for Wiz FedRAMP (`app.wiz.us`). Omit for standard Wiz. | No       |

6. Click **Create**.

`WIZ_CLIENT_SECRET` is held in Firefly's secret store and encrypted at rest. It is never written to logs, API responses, or run output.

For full details on creating and managing variable sets, see [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets).

### Step 2: Consume the Variable Set at the Right Scope

The Wiz variable set can be consumed at **Organization**, **Project**, or **Workspace** scope, and standard variable inheritance applies — a more specific scope overrides a broader one. This determines how widely the integration takes effect:

* **Organization Variables:** every workspace in the organization becomes Wiz-integrated.
* **Project:** all workspaces in that project and its sub-projects become Wiz-integrated.
* **Workspace:** only that workspace becomes Wiz-integrated.

Consuming at organization scope is the most direct way to make Wiz the policy authority everywhere. Consuming at project or workspace scope lets you roll the integration out incrementally, or keep it scoped to the environments that need it.

### Step 3: Verify

Open the workspace and check the **Workspace Summary**. A Wiz-integrated workspace displays a **Wiz Integrations** indication confirming the connection.

The indication reports only that the workspace is integrated. It does not list policies — those live in your Wiz tenant and are not known to Firefly.

Then trigger a run. A correctly configured workspace passes through the **Checking Integrations** status and reaches the Guardrails step with Wiz results present.

## Setting Up in an Existing CI/CD Pipeline

In this model your pipeline runs the Wiz CLI and passes the result to Firefly. Firefly ingests, persists, gates on, and displays the result, but does not run the scan itself. There is no pre-init connection check in this model and no **Checking Integrations** status — validating that Wiz is reachable is your pipeline's responsibility.

This section assumes you already have `fireflyci` integrated into your pipeline. If you don't, set that up first — see [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows).

> **Verified versions:** The steps below were verified end-to-end on a live GitLab CI pipeline using `fireflyci` v0.6.26 and Wiz CLI 0.109.16. The `--wiz-scan-file` flag requires `fireflyci` v0.6.26 or later.

Add the following three steps to the job that runs your plan, before your `fireflyci post-plan` step.

### Step 1: Install the Wiz CLI

Pin the version and verify the checksum rather than tracking `latest`, so a Wiz-side release cannot change your gate's behavior mid-pipeline:

```sh
WIZCLI_VERSION=0.109.16
WIZCLI_SHA256=29284fdc93e09ae2108cf06c0206b4be8eaff2a2280eecf2422209787a7d451d

curl -fsSL -o wizcli "https://downloads.wiz.io/wizcli/${WIZCLI_VERSION}/wizcli-linux-amd64"
echo "${WIZCLI_SHA256}  wizcli" | sha256sum -c -
chmod a+x wizcli && ln -s "$(pwd)/wizcli" /usr/local/bin/wizcli
```

Version `0.109.16` is the version Firefly pins in its own runner image.

> **Note:** The SHA256 above is specific to version `0.109.16` of the `linux-amd64` binary. If you bump `WIZCLI_VERSION`, you must update `WIZCLI_SHA256` to match, or `sha256sum -c` will fail the job. Obtain the checksum for a different version or architecture from Wiz.

### Step 2: Authenticate

```sh
export WIZ_DIR="$CI_PROJECT_DIR/.wiz-$CI_JOB_ID"
mkdir -p "$WIZ_DIR"
wizcli auth
```

Two details matter here:

* **Pass credentials through the environment, not as flags.** `wizcli auth` reads `WIZ_CLIENT_ID` and `WIZ_CLIENT_SECRET` (and optionally `WIZ_ENV`) directly from the environment. The `--id` and `--secret` flags exist but should not be used: command-line arguments are visible to any process on the host through `/proc/<pid>/cmdline` and `ps`, which exposes your Wiz secret to anything else sharing the runner. Store the credentials as masked/protected CI/CD variables instead.
* **Set a per-job `WIZ_DIR`.** The Wiz CLI writes its authentication token into `WIZ_DIR`. If several jobs share a runner and share the default location — which is exactly what happens in a pipeline that fans out one job per module — they will overwrite each other's token, and jobs will fail to authenticate intermittently. Deriving `WIZ_DIR` from the job ID, as above, isolates them.

### Step 3: Scan and Pass the Result to Firefly

Run the scan after `terraform plan`, then point `fireflyci post-plan` at the resulting file:

```sh
rm -f "$PWD/wiz_scan.json"
wizcli iac scan --path . -f json -o "$PWD/wiz_scan.json,json" --name "${CI_PROJECT_NAME}-${CI_JOB_ID}"

fireflyci post-plan \
  -l plan_log.json \
  -f plan.json \
  --plan-output-raw-log-file plan_output_raw.log \
  -w "<YOUR_UNIQUE_WORKSPACE_NAME>" \
  --wiz-scan-file "$PWD/wiz_scan.json"
```

* `rm -f` clears any stale result from a previous run in a reused workspace directory, so a failed scan cannot be silently gated on an old passing result.
* `--name` gives the scan a label in the Wiz dashboard. Use something unique per run so scans are traceable.
* `--wiz-scan-file` is the flag that hands the result to Firefly. If `post-plan` determines the run should be blocked, it exits non-zero, which stops your pipeline before `apply`.

> **Important: `-o "$PWD/wiz_scan.json,json"` must be written exactly as shown.** Both halves of that value are load-bearing, and both fail silently if you get them wrong.
>
> **The `,json` suffix is what makes the file JSON.** The output file's format is set by `-o` itself, not by `-f`. The `-f json` flag only controls how results are styled on stdout. A bare `-o wiz_scan.json` writes a human-readable report instead: Firefly parses it as zero coverage, discards it, and then fail-closed blocks the run. The result is that **every** run is blocked, and nothing in the error message points at the flag that caused it.
>
> **The path must be absolute.** A relative path is resolved against the working directory of whichever command is using it, and `post-plan` may not share the scan's working directory. Any pipeline that `cd`s into a module directory — which every per-module pipeline does — will have the two diverge, and the run will be blocked with `expected a valid Wiz scan result and did not receive one`. Using `$PWD` keeps the path absolute and unambiguous.

### Step 4: Report the Apply

Your existing `fireflyci post-apply` step needs no Wiz-specific changes. It continues to report apply results to Firefly for visibility.

### Limits of Enforcement in This Model

Firefly can only gate a run it is told about. If a pipeline never invokes `fireflyci post-plan`, or invokes it but ignores its exit code, the `apply` will proceed regardless of the Wiz verdict.

This is a weaker guarantee than the Firefly-managed model, where Firefly controls the run end to end. If your requirement is that a failing Wiz verdict can never be bypassed, use Firefly-managed workspaces, or protect the pipeline definition itself so the `fireflyci` step cannot be removed.

## Understanding Wiz Results in the Guardrails Step

Open a run and select the **Guardrails** step. For a Wiz-integrated workspace it shows a **Wiz policies** panel, with a green **Connected** chip confirming the integration is active.

### Overall Verdict

Wiz returns a single verdict for the scan, which Firefly displays verbatim without remapping:

| Verdict            | Meaning                                                     | Blocks the run? |
| ------------------ | ----------------------------------------------------------- | --------------- |
| `PASSED_BY_POLICY` | No policy failures.                                         | No              |
| `WARN_BY_POLICY`   | Findings exist, but not at a level Wiz treats as a failure. | No              |
| `FAILED_BY_POLICY` | At least one Wiz policy failed.                             | **Yes**         |

### Per-Policy Breakdown

Beneath the overall verdict is one row per policy Wiz evaluated, each with a result indicator, a severity, and the verdict Wiz returned:

* **Red ✕ — `Failed by Policy`:** a hard failure. This blocks the run.
* **Amber ⚠ — `Passed`:** a soft failure. The policy flagged something, but the Wiz verdict still passed, so this is informational and does not block. This is the `WARN_BY_POLICY` case.
* **Green ✓ — `Passed`:** no findings.

When any policy shows `Failed by Policy`, the **Apply** action is disabled and marked with a lock badge.

### Findings

Individual findings are listed below the policy breakdown:

* **Rule matches:** the rule name plus the location in your configuration, as `fileName:lineNumber`.
* **Secrets:** any secrets Wiz detected in the scanned configuration, with their type and location.
* **Report link:** a deep link to the full report in the Wiz dashboard, for the complete detail Wiz holds on the scan.

A scan with no findings at all is a valid, successful result — not an error.

### Firefly Custom Policy Results

Firefly custom policy results appear in the same Guardrails step, alongside the Wiz results. Both are shown because a run can be blocked by either a Wiz `FAILED_BY_POLICY` verdict or a Firefly custom policy set to **Strict Block**, and you need to see which one caused it. A blocked run is always attributable to the specific policy that blocked it.

## What Blocks a Run

A run is blocked before `apply` if any of the following is true:

* **Wiz returns `FAILED_BY_POLICY`.**
* **A Firefly custom policy with Violation Behavior = Strict Block is violated.** See [Creating Guardrail Rules](/detailed-guides/workflows/creating-guardrail-rules).
* **The Wiz scan cannot be completed.** If the connection check passed but the scan then crashes, exits non-zero, cannot reach Wiz, or returns malformed output, the run is blocked.
* **No valid Wiz result is available.** In the CI/CD model, if the pipeline sends no scan result, or sends one that is empty, malformed, or in the wrong format, the run is blocked with an error stating that a valid Wiz result was expected and not received.

These last two are deliberate: this is a security gate, so it **fails closed**. A scan that errors is never treated as a scan that passed.

`WARN_BY_POLICY` and `PASSED_BY_POLICY` do not block, and neither does a violated custom policy that is not set to Strict Block.

## Limitations and Considerations

* **Firefly does not control which Wiz policies run.** Policy selection is entirely a function of your Wiz tenant configuration. This is intentional: it means policy changes you make in Wiz take effect on Firefly runs immediately, with no corresponding change in Firefly. It also means Firefly cannot scope, exclude, or threshold Wiz policies for a particular workspace — do that in Wiz.
* **Severity thresholds are not configurable in Firefly.** Firefly blocks on the verdict Wiz returns. If you want severity-based gating, configure it in your Wiz policies.
* **Built-in Firefly policy scans and kicks scans are skipped** for integrated workspaces. If you rely on specific Firefly built-in policies today, reproduce them as Wiz policies or as Firefly custom policies before enabling the integration.
* **The Wiz CLI is Linux amd64/arm64 only**, which constrains self-hosted runner pools and CI/CD job images.
* **Enabling is implicit.** Because resolved credentials are the trigger, consuming the Wiz variable set at organization scope silently changes scan behavior for every workspace in the organization. Roll out at project or workspace scope first if you want to stage the change.

## Troubleshooting

| Symptom                                                                                                                          | Likely cause                                                                                                 | Resolution                                                                                                                                                                                                                                 |
| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Run fails at **Checking Integrations** with **Init Failed**                                                                      | Invalid or missing credentials, or Wiz is unreachable.                                                       | Verify `WIZ_CLIENT_ID` and `WIZ_CLIENT_SECRET` resolve for the workspace and are correct. If you use Wiz GovCloud or FedRAMP, confirm `WIZ_ENV` is set to `gov` or `fedramp`. Confirm the runner has egress to the Wiz auth and API hosts. |
| **Init Failed** with no Wiz output at all                                                                                        | The Wiz CLI binary could not be provisioned on the runner.                                                   | Confirm the runner can reach `downloads.wiz.io`, and that a self-hosted runner is Linux amd64 or arm64.                                                                                                                                    |
| Every CI/CD run is blocked with `expected a valid Wiz scan result and did not receive one`, and the scan itself looks successful | The `,json` suffix is missing from `-o`, so the file is a human-readable report rather than JSON.            | Use `-o "$PWD/wiz_scan.json,json"` exactly. See [Step 3](#step-3-scan-and-pass-the-result-to-firefly).                                                                                                                                     |
| Same error, in a pipeline that runs one job per module                                                                           | A relative path to `wiz_scan.json` is resolving against a different working directory than `post-plan` uses. | Use an absolute path — `"$PWD/wiz_scan.json"` — in both the `-o` value and `--wiz-scan-file`.                                                                                                                                              |
| `fireflyci: unknown flag: --wiz-scan-file`                                                                                       | `fireflyci` predates the flag.                                                                               | Upgrade to `fireflyci` v0.6.26 or later.                                                                                                                                                                                                   |
| Jobs fail to authenticate to Wiz intermittently when several run at once                                                         | Concurrent jobs on a shared runner are overwriting each other's auth token in a shared `WIZ_DIR`.            | Set a per-job `WIZ_DIR`, as in [Step 2](#step-2-authenticate).                                                                                                                                                                             |
| `sha256sum -c` fails during install                                                                                              | `WIZCLI_VERSION` was changed without updating `WIZCLI_SHA256`, or the architecture differs.                  | Update the checksum to match the version and architecture you are downloading.                                                                                                                                                             |
| Run is blocked but the Guardrails step shows no failing policy                                                                   | The scan could not be completed or returned unparseable output, so the fail-closed gate applied.             | Check the Wiz CLI exit code and output in the job log for the underlying failure.                                                                                                                                                          |
| A policy shows amber ⚠ but the run proceeds                                                                                      | Expected behavior — this is the `WARN_BY_POLICY` soft-fail case, which is informational.                     | To make these block, raise their severity or strictness in your Wiz policy configuration.                                                                                                                                                  |
| Firefly built-in policy violations no longer appear                                                                              | Expected behavior — built-in policy scans are skipped for Wiz-integrated workspaces.                         | Reproduce the checks you need as Wiz policies or Firefly custom policies.                                                                                                                                                                  |

## Security Considerations

* **Secret handling.** In the Firefly-managed model, `WIZ_CLIENT_SECRET` is stored in Firefly's secret store, encrypted at rest, and never written to logs, API responses, or run output. In the CI/CD model, Firefly never receives your Wiz credentials at all — they stay in your CI/CD environment, and Firefly receives only the scan output.
* **Least privilege.** The Wiz service account requires read-only permissions.
* **Do not pass credentials as CLI flags.** See [Step 2](#step-2-authenticate).
* **Scan result contents.** Wiz results may include resource names, configuration detail, and the location of detected secrets. Firefly applies the same access controls to them as to other run data, and they are visible to anyone who can view the run.
* **Binary integrity.** Pin the Wiz CLI version and verify its checksum, as shown in [Step 1](#step-1-install-the-wiz-cli).


# Creating a Self-Hosted Runner Pool

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
> * [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
> * [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.
> * [Integrating Existing CI/CD Pipelines with Firefly Workflows](/integrations/workflows): For hybrid or external CI/CD integration.
> * [Firefly Workflows Example Pipelines](https://github.com/gofireflyio/workflows-examples): Real-world pipeline and integration templates for Jenkins, GitHub Actions, and more.

Self-hosted runners allow you to execute Terraform, OpenTofu, and Terragrunt operations within your own infrastructure while maintaining full control over network access, data residency, and compliance requirements. By deploying runner pools in your environment, you can ensure that all IaC operations run within your network boundaries while still benefiting from Firefly's orchestration, monitoring, and governance features.

This document provides a comprehensive guide on how to create and configure self-hosted runner pools in Firefly.

## Creating a New Self-Hosted Runner Pool: Step-by-Step

Follow the wizard in the Firefly UI to create a new self-hosted runner pool.

**Procedure:**

1. **Navigate to Self-Hosted Runners:**
   * In the Firefly UI, click on **Workflows** from the main navigation menu.
   * Then, click on the **Self Runner Runners** sub-section.
2. **Add New Runner Pool:**
   * Click on the **+ New runner pool** button.
3. **Enter Runner Pool Details:**
   * **Name:**
     * Provide a unique name for your self-hosted runner pool (3-64 characters).
     * Use alphanumeric characters, hyphens, and underscores only.
     * The name must be unique within your organization.
     * *Example:* `production-runners`, `us-east-1-pool`, `secure-network-runners`.
   * **Labels (Optional):**
     * Add labels for workspace targeting and organization. Workspaces can target specific pools using these labels.
   * **Runner Agent Replicas:**
     * Number of runner agents to deploy. Can be scaled up or down later.
   * **Project Assignment (Optional):**
     * Select the project this runner pool will be assigned to. Assigning to the global project means that this runner pool will be available to all projects.
   * **Release Name:**
     * Provide a unique name for the release name (3-64 characters).
     * Use alphanumeric characters, hyphens, and underscores only.
   * **Namespace Name:**
     * Provide a unique name for the namespace name (3-64 characters).
     * Use alphanumeric characters, hyphens, and underscores only.
   * **Description (Optional):**
     * Add a free-text explanation to help identify the runner pool's purpose.
     * *Example:* "Production runner pool for secure network deployments in us-east-1".
4. **Press Create to View Installation Instructions:**
   * Click **Create** to create the runner pool and view the installation instructions.
5. **Installation Instructions:**
   * Deploy runners in your Kubernetes cluster using Helm to automatically manage multiple runner agents as a single pool. Run the Helm command below. The pool status will change from Inactive to Active once the agents successfully connect and send their first heartbeat to Firefly.
   * Copy the generated Helm command from the installation instructions.
   * Deploy the command in your Kubernetes cluster.
   * > **Important:**
   * > * Firefly doesn't save the JWT token, meaning that once this wizard is closed, the instructions cannot be replicated.
   * > * Currently, AWS credentials can only be passed through environment variables to enable role assumption. Other authentication methods are not yet supported.
6. **Press Next to go to the Completion step:**
   * Click **Next** to proceed to the completion step.
7. **Press Done to close the wizard:**
   * Click **Done** to close the wizard.

## Self-Hosted Runner Pool Status

The self-hosted runner pool status will change from **Inactive** to **Healthy** once the self-hosted runner is deployed in your Kubernetes cluster and Firefly receives a heartbeat from the runner agents. This indicates that the runner pool is successfully connected and ready to execute IaC operations.

## Assigning a Self-Hosted Runner Pool: Firefly Managed Workspace and Projects

Once you have created a self-hosted runner pool, you can assign it to workspaces or projects to control where your IaC operations execute.

### Connecting Self-Hosted Runner to a Project or Workspace

1. Navigate to **Workflows > Self Hosted Runners**.
2. Select the runner pool you want to assign to a project or workspace and select the Assign action from the action list.
3. Choose the relevant projects and workspace you want this runner pool to be assigned to.
4. Click Assign to save the changes.

### Assigning to a Project

When you assign a runner pool to a project, all workspaces within that project and its sub-projects automatically inherit the runner pool assignment. This provides a centralized way to manage runner assignments across multiple workspaces.

**To assign a runner pool to a project:**

1. Navigate to **Workflows > Projects & Variables**.
2. Select the project you want to configure and select the Edit action from the action list.
3. In the edit project wizard locate the **Runner Pool** field.
4. Select the runner pool from the dropdown menu.
5. Save the changes.

All workspaces created within this project will automatically use the assigned runner pool for execution.

### Assigning to a Workspace

You can also assign a runner pool directly to a specific workspace. Workspace-level assignments override project-level assignments, allowing you to customize runner selection for individual workspaces when needed.

**To assign a runner pool to a workspace:**

1. Navigate to **Workflows > Workspaces**.
2. Select the workspace you want to configure and select the Edit action from the action list.
3. In the edit workspace wizard click next until you are at the **Runner Configuration** step.
4. Select the "self-hosted" in the Runner Type section.
5. Click next and Done to save the changes.

The workspace will use the selected runner pool for all Terraform/OpenTofu/Terragrunt operations.

### Runner Pool Inheritance

Runner pool assignments follow a hierarchical inheritance model:

* **Project Level:** When assigned to a project, all child projects and workspaces inherit the runner pool.
* **Workspace Level:** Workspace-level assignments override project-level assignments.
* **Default Behavior:** If no runner pool is assigned at either level, workspaces use Firefly's managed runners.

This inheritance model allows you to set default runner pools at the project level while maintaining the flexibility to override at the workspace level when specific requirements exist.


# AWS Authentication via IRSA

This guide explains how to configure a Firefly self-hosted runner on EKS to authenticate with AWS using IAM Roles for Service Accounts (IRSA). With IRSA, Terraform running inside the runner can access AWS resources (state backend, provider APIs) without static credentials.

## Prerequisites

### 1. EKS Cluster with OIDC Provider

Your EKS cluster must have an OpenID Connect (OIDC) provider configured. Verify with:

```bash
aws eks describe-cluster --name <cluster-name> \
  --query "cluster.identity.oidc.issuer" --output text
```

### 2. IAM Role

Create an IAM role that:

* Has a trust policy allowing the Kubernetes service account to assume it via `sts:AssumeRoleWithWebIdentity`
* Has permissions for the S3 state backend and any AWS resources Terraform will manage

## Configuration

### Runner Image

Update the runner to an image that includes IRSA credential forwarding. Use `latest` or pin a specific tag:

```yaml
repository:
  tag: "latest"  # or a specific version tag
```

### Helm Chart

Update to the latest version of the `ci-runner-worker` chart:

```yaml
chart: "ci-runner-worker"
targetRevision: "0.0.10"
```

### Helm Values

Annotate the service account with the IAM role ARN:

```yaml
serviceAccount:
  annotations:
    eks.amazonaws.com/role-arn: "arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>"
```

The EKS webhook uses this annotation to automatically inject the projected token volume, volumeMounts, and `AWS_ROLE_ARN` / `AWS_WEB_IDENTITY_TOKEN_FILE` env vars into all containers in the pod. No manual volume or volumeMount configuration is required.

### Workspace Variables

Set the following as **environment variables** on the workspace in the Firefly UI:

| Variable             | Value                                |
| -------------------- | ------------------------------------ |
| `AWS_DEFAULT_REGION` | Target AWS region (e.g. `eu-west-1`) |
| `AWS_REGION`         | Target AWS region (e.g. `eu-west-1`) |

### Terraform Configuration

No special provider configuration is needed. The AWS SDK automatically detects the IRSA env vars and calls `sts:AssumeRoleWithWebIdentity`:

```hcl
provider "aws" {
}

terraform {
  backend "s3" {
    bucket = "<BUCKET_NAME>"
    key    = "<STATE_KEY>"
    region = "<REGION>"
  }
}
```

## Cross-Account Terraform Execution with IRSA on Self-Hosted Runners

Firefly self-hosted runners support IAM Roles for Service Accounts (IRSA) for authenticating Terraform operations across multiple AWS accounts — without requiring a dedicated runner in each account.

### How It Works

The setup relies on IAM role chaining, where the runner's service account role assumes a role in a target account. This is standard Terraform behavior using the S3 backend's `role_arn` configuration.

### Configuration Steps

1. In the Helm chart, define the IAM role ARN (Role A) under `.Values.serviceAccount.annotations`. This role must reside in the same AWS account as the Firefly runners.
2. In `providers.tf`, set `terraform.backend.s3.role_arn` to a role in the target AWS account (Role B).
3. Ensure the appropriate cross-account trust is in place: Role A must have permission to assume Role B (via its IAM policy), and Role B's trust policy must allow Role A to assume it.

Once configured, `terraform plan` and other operations execute against the target AWS account by design — eliminating the need to deploy a runner in every account.

## Limitations

1. **EKS only.** IRSA is an EKS-specific feature. This approach does not work on other Kubernetes distributions (GKE, AKS, vanilla k8s). Alternative authentication methods (static credentials via workspace variables) are needed there.
2. **Single AWS account per runner.** The IRSA role is bound to the runner's service account. All Terraform workspaces executed by that runner assume the same IAM role.
3. **Token expiry.** The projected token has a default expiration of 24 hours. Kubelet automatically refreshes it before expiry, however, long-running Terraform operations that exceed the token's remaining lifetime may fail mid-operation.


# Triggering Workspace Deployment

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
> * [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
> * [Creating Variable Sets](/detailed-guides/workflows/creating-variable-sets): Managing reusable variable collections.

Workspace deployment in Firefly Workflows allows you to trigger plan or plan+apply executions for your Infrastructure as Code (IaC) directly from the UI. This process enables you to validate changes, review execution plans, and deploy infrastructure updates with full control over the deployment process. Whether you need to perform a quick validation with a plan-only run or execute a complete deployment with automatic or manual apply, the Deploy Workspace modal provides all the necessary controls to manage your infrastructure deployments safely and efficiently.

**Key Benefits of Workspace Deployment:**

* **Flexible Execution:** Choose between plan-only runs for validation or full plan+apply deployments.
* **Branch Control:** Deploy from any branch to support feature testing and environment-specific deployments.
* **Automated Workflows:** Configure automatic apply after plan completion or require manual approval for enhanced control.
* **Custom Arguments:** Pass additional CLI arguments for advanced Terraform/OpenTofu/Terragrunt configurations.

## Triggering a Workspace Deployment: Step-by-Step

Follow these steps to trigger a deployment for your workspace using the *Deploy Workspace* modal.

**Procedure:**

1. **Navigate to Your Workspace:**
   * In the Firefly UI, click on **Workflows > Workspaces** from the main navigation menu.
   * Select the workspace you want to deploy from the workspace list.
2. **Open the Deploy Modal:**
   * Click the **Deploy** button in the workspace actions menu.
   * The Deploy Workspace modal will appear with deployment configuration options.
3. **Configure Deployment Settings:**
   * **Select Your Branch:**
     * Choose which Git branch to deploy from using the Branch dropdown. This determines which version of your Infrastructure as Code will be executed.
     * **Production deployments:** Use `main` or `master` for stable, tested code
     * **Testing new features:** Use feature branches like `feature/new-vpc` to test changes before merging
   * **Choose Your Deployment Type:**
     * Use the **Run Apply** checkbox to determine whether you want to preview changes or actually apply them.
     * **Plan only** (unchecked): Generate a preview of changes without making any modifications. Perfect for validating changes before deployment.
     * **Plan + Apply** (checked): Generate a plan and then apply the changes to your infrastructure.
   * **Set Apply Behavior (when Run Apply is enabled):**
     * When you've chosen to run both plan and apply, use the **Apply Rules** option to control when changes are applied.
     * **Manual:** Requires manual approval after reviewing the plan. Recommended for production environments.
     * **Auto:** Automatically applies changes after a successful plan. Ideal for development environments.
   * **Add Custom Arguments (Optional):**

     * Use the **Additional Run Arguments** field to pass extra parameters to Terraform/OpenTofu/Terragrunt. For example:
       * `-parallelism=5` - Limit concurrent operations to avoid resource conflicts.

       * `-var="environment=staging"` - Override variable values for specific environments.

       * `-target=module.vpc` - Apply changes to specific resources only.

     > **Tip:** To inject a `.tfvars` file on every run, set the `TF_CLI_ARGS_plan` and/or `TF_CLI_ARGS_apply` environment variables on the workspace (with value `-var-file=<name>.tfvars`) instead of using this field. See [Injecting a `.tfvars` File at Execution](/detailed-guides/workflows/creating-workflows#injecting-a-tfvars-file-at-execution).
4. **Review and Execute:**
   * Verify all configuration settings are correct for your deployment needs.
   * Click **Deploy** to start the workspace deployment.
   * Click **Cancel** to abort the deployment process.

## Deployment Execution Flow

Once you trigger a deployment, the following process occurs:

1. **Plan Phase:** Firefly executes `terraform plan` (or equivalent) using your selected branch and arguments.
2. **Plan Review:** View the execution plan to understand what changes will be applied.
3. **Apply Decision:**
   * **Auto Apply:** Changes are automatically applied after successful plan.
   * **Manual Apply:** You must manually approve the apply operation.
   * **Guardrail Checks:** If any Guardrail rules are violated, the deployment will stop and you will be notified.
   * **Plan-Only:** Execution stops after plan completion for review.
4. **Apply Phase:** If approved, Firefly executes `terraform apply` to implement the changes.
5. **Completion:** Review deployment results and any output values.

## Best Practices for Workspace Deployment

* **Branch Strategy:** Use feature branches for testing and `main`/`master` for production deployments.
* **Plan-Only First:** Run plan-only executions before applying changes to production environments.
* **Manual Approval:** Use manual apply rules for critical infrastructure changes.
* **Incremental Deployment:** Deploy small, focused changes rather than large batches for easier troubleshooting.
* **Review Plans:** Always review the execution plan before applying changes.
* **Environment Separation:** Use different apply rules for different environments (manual for production, auto for development).
* **Custom Arguments:** Leverage additional arguments for deployment-specific configurations.
* **Monitoring:** Monitor deployment progress and review logs for any issues.

## Common Deployment Scenarios

### Development Environment Deployment

* **Branch:** feature/new-feature
* **Run Apply:** ✓ Checked
* **Apply Rules:** Auto
* **Additional Arguments:** -var="environment=dev"

### Production Environment Deployment

* **Branch:** main
* **Run Apply:** ✓ Checked
* **Apply Rules:** Manual
* **Additional Arguments:** -parallelism=3

### Plan-Only Validation

* **Branch:** feature/infrastructure-update
* **Run Apply:** ✗ Unchecked
* **Apply Rules:** N/A (disabled)
* **Additional Arguments:** (none)

### Targeted Resource Deployment

* **Branch:** main
* **Run Apply:** ✓ Checked
* **Apply Rules:** Manual
* **Additional Arguments:** -target=module.database

By following this guide and implementing these best practices, you can safely and efficiently manage your infrastructure deployments through Firefly Workflows while maintaining full control over the deployment process.


# Remote State Management

> **Related Guides and Examples:**
>
> * [Overview: Firefly Workflows and Guardrails](/detailed-guides/workflows): High-level concepts and options.
> * [Creating New Firefly Workflows](/detailed-guides/workflows/creating-workflows): How to set up managed workflows.
> * [Creating Guardrail Rules in Firefly](/detailed-guides/workflows/creating-guardrail-rules): How to define and enforce policies and best practices.
> * [Creating Projects](/detailed-guides/workflows/creating-projects): How to create projects to group IaC orchestration resources and control access.
> * [Triggering Workspace Deployment](/detailed-guides/workflows/trigger-deploy): How to trigger a workspace deployment from the Firefly UI.
> * [Local Execution (State-Only Workspaces)](/detailed-guides/workflows/local-execution): Use Firefly as your backend while running `plan`/`apply` yourself, with the workspace created on demand.

Firefly offers a sophisticated state backend synchronized with the rest of the application to manage your Terraform state and maximize security and convenience—available for workspaces configured with Firefly runner or Self-hosted runner pool.

> **Choosing a mode:** This page covers using Firefly as your backend for workspaces whose execution is handled by a **Firefly or self-hosted runner**, with the workspace **pre-created** in the UI (using a `backend "remote"` block). If you would rather run `plan`/`apply` **locally** yourself and have Firefly **auto-create** a state-only, VCS-less workspace (using a `cloud {}` block), see [Local Execution (State-Only Workspaces)](/detailed-guides/workflows/local-execution) instead.

## State History

You can view your stack's state history in Firefly. Navigate to the workspace, hover over the actions and select **View Assets**. In the modal that opens you can see all the assets created by this workspace, when each was created, and the ability to download the state file.

> **Note:** Not all runs or tasks will trigger a new state version, so you should not expect to see an exhaustive list of your runs and tasks in this list. For example, runs that produce no Terraform changes do not result in a new state version being created.

## Limitations

* **OpenTofu versions:** All versions are supported.
* **Workspace name format:** Workspace names cannot contain spaces in the HCL backend block. Note that while Firefly allows spaces in workspace names within the UI, the name used in your backend configuration must not contain spaces.
* **Workspace creation only:** An existing workspace cannot be edited to use Firefly state management. To use this feature, create a new workspace and enable Firefly state management during the creation process.

## Remote Management Workspace Set-up

### Workspace Configuration

To enable state management for a workspace:

**New Workspace**

In the Execution Configuration step, enable the **Firefly Remote Backend Configuration** option.

### Migration

#### Prerequisites, account ID, Workspace and authentication

Before migrating state into Firefly:

* **Workspace:** Create the Firefly workspace first and enable **Firefly Remote Backend Configuration** (see [Workspace configuration](#workspace-configuration) above). The workspace name you use in HCL must match an existing workspace; migration targets that workspace’s remote state.
* **`organization` in the backend block:** This value is your **Firefly account ID** (it is not an arbitrary label). In the Firefly console, open [**Integrations**](https://app.firefly.ai/integrations); the account ID appears in the **top left corner**, under **Connected integrations**.
* **API token:** Commands that talk to `api.gofirefly.io` must authenticate. Set a Firefly JWT (from an API key pair) in the environment variable Terraform/OpenTofu expects for this hostname:

```bash
export TF_TOKEN_api_gofirefly_io="<your-firefly-jwt>"
```

For how to obtain the JWT from your access and secret keys, see [Authentication](/general-information/api/auth#authentication).

#### Firefly backend configuration

To use the Firefly remote backend, configure your backend block as follows. Replace `<your-firefly-account-id>` with your account ID from **Integrations** (top left corner, under **Connected integrations**), and `<your-firefly-workspace-name>` with the workspace name (no spaces in this field; see [Limitations](#limitations)).

```hcl
terraform {
  backend "remote" {
    hostname     = "api.gofirefly.io"
    organization = "<your-firefly-account-id>"
    workspaces {
      name = "<your-firefly-workspace-name>"
    }
  }
}
```

#### Migrating from Terraform remote backend to OpenTofu

If you are switching from Terraform to OpenTofu and currently use Terraform Cloud’s `remote` backend, add `hostname = "app.terraform.io"` to your existing backend block, then run the migration command. This step moves your working copy to OpenTofu while state remains on Terraform Cloud.

Existing backend block:

```hcl
terraform {
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "your-organization"
    workspaces {
      name = "your-workspace"
    }
  }
}
```

Then run:

```bash
tofu init -migrate-state
```

#### Migrating from Terraform `cloud` backend to OpenTofu + Firefly

If you are switching from Terraform to OpenTofu and currently use a `cloud` block, use the manual pull/push flow (not `-migrate-state` across `cloud` → `remote` to Firefly).

1. **Add hostname to your existing `cloud` block:**

```hcl
terraform {
  cloud {
    hostname     = "app.terraform.io"
    organization = "your-organization"
    workspaces {
      name = "your-workspace"
    }
  }
}
```

2. **Pull and validate the current state:**

```bash
tofu init
tofu state pull > terraform.tfstate.backup
tofu show terraform.tfstate.backup   # If this succeeds, the state is valid
```

3. **Replace the `cloud` block** with the Firefly `remote` backend:

```hcl
terraform {
  backend "remote" {
    hostname     = "api.gofirefly.io"
    organization = "<your-firefly-account-id>"
    workspaces {
      name = "<your-firefly-workspace-name>"
    }
  }
}
```

4. **Reinitialize and push state:**

```bash
rm -rf .terraform
tofu init -reconfigure
tofu state push terraform.tfstate.backup
```

> **Note:** If a state already exists on the workspace and you need to override it, append the `-force` flag:

```bash
tofu state push -force terraform.tfstate.backup
```

> **Note:** A Firefly workspace’s remote state is **unique** to that workspace. You cannot point several different backends or stacks at the **same** workspace name and treat them as separate state buckets—each upload targets that single workspace, and the **latest** push or successful apply **replaces** the stored state for it. Use **one workspace per distinct state** (or split stacks at the Terraform/OpenTofu level) so you do not overwrite another environment’s state by mistake.


# Local Execution (State-Only Workspaces)

Firefly can act as the **remote state backend** for your Terraform projects. You point Terraform at Firefly with a standard `cloud {}` block, and Firefly stores your state, tracks every version, and manages state locking — while your `terraform plan` and `terraform apply` continue to run locally on your own machine or CI runner.

No version-control connection is required. This is often called a **state-only** or **VCS-less** workspace: Firefly creates it for you automatically the first time you run `terraform init`, and it appears in the Firefly console right away — before you have applied anything.

> **Choosing a state backend mode:** This page covers **local execution**, where Firefly stores your state but you run Terraform yourself and the workspace is created on demand. If instead you want Firefly (or a self-hosted runner pool) to *run* `plan` and `apply` for you against a pre-created workspace, see [Remote State Management](/detailed-guides/workflows/remote-state-management). The two modes use different backend blocks (`cloud {}` here vs. `backend "remote"` there) — pick the one that matches how you want execution handled.

***

## Overview

When you use Firefly as your backend:

* **Your state lives in Firefly.** Every `apply` uploads a new, versioned copy of your Terraform state. You can browse state versions and serials in the console.
* **Execution stays local.** Firefly does not run Terraform for you in this mode. `plan` and `apply` execute wherever you run them; only the resulting state is sent to Firefly. The workspace's execution mode is therefore `local`.
* **Locking is handled for you.** Concurrent `apply`s are serialized through Firefly's state lock, exactly as with any Terraform remote backend.
* **The workspace is created on demand.** You do not pre-create anything in the UI. The first `terraform init` that references a new workspace name creates it.

### When to use this

Use a state-only workspace when you want Firefly to be the source of truth for your Terraform state and to give you visibility into that state, but you want to keep driving Terraform yourself — from a laptop, a script, or an existing CI pipeline — rather than connecting a Git repository.

***

## Prerequisites

* **Terraform** installed (`terraform version`).
* A **Firefly account**, and your **account ID** — a 24-character hexadecimal string. This is the value you will use for `organization`. It is **not** your company or account display name.
* **`curl`** and **`jq`** (or any HTTP client) to exchange your access key for a token in Step 2.

Throughout this guide the Firefly API host is **`api.firefly.ai`**. Use that host for both the token exchange and the `cloud {}` block.

***

## Step 1 — Create an access key in the console

Access keys are how you authenticate to the Firefly API from outside the browser.

1. In the Firefly console, go to **Settings → Access Management**.
2. Under the **API Keys** section, click **New API Key** to generate a new **access key** and **secret key** pair.
3. **Copy the secret key immediately** — it is shown only once and cannot be retrieved later. Store it somewhere safe (a password manager or secrets vault).

You now have two values:

* an **access key** (an identifier), and
* a **secret key** (the credential).

> For more on managing keys, roles, and permissions, see [Access Management & RBAC](/getting-started/access-management-rbac).

***

## Step 2 — Exchange the access key for a bearer token

Terraform authenticates to Firefly with a **bearer token (a JWT)**, not with the access key directly. You mint that token by calling the login endpoint with your key pair.

> There is **no `terraform login`** flow for Firefly. Do not run `terraform login` — mint the token yourself as shown here.

```bash
TOKEN=$(curl -s -X POST "https://api.firefly.ai/v2/login" \
  -H 'Content-Type: application/json' \
  -d '{
        "accessKey": "YOUR_ACCESS_KEY",
        "secretKey": "YOUR_SECRET_KEY",
        "duration":  "1y"
      }' | jq -r .accessToken)
```

The token is returned in the **`accessToken`** field (note the camelCase). The snippet above extracts it into a `TOKEN` shell variable.

You can check for a successful response by echoing the `TOKEN` variable:

```bash
echo $TOKEN
```

### The `duration` attribute

`duration` is **optional** and controls how long the minted token remains valid.

* **Format:** `<number><unit>`, where the unit is one of `h` (hours), `d` (days), `w` (weeks), `m` (months), or `y` (years). Examples: `1h`, `12h`, `7d`, `2w`, `6m`, `1y`.
* **Default:** `24h` if you omit the field.
* **Maximum:** `1y`. A request for `"duration": "1y"` returns a token valid for a full 365 days; omitting the field yields the 24-hour default.

Choose the **shortest** duration that fits your rotation cadence. A short-lived token limits your exposure if it is ever leaked — see [Security and token lifecycle](#security-and-token-lifecycle) below. Long-lived tokens (up to a year) are convenient for stable CI systems but should be stored in a secrets manager and rotated deliberately.

***

## Step 3 — Store the token in a Terraform credentials file

Terraform reads a **per-host** token from a JSON credentials file. Create one and store the token **raw** — do not prefix it with `Bearer`; Terraform adds that itself when it calls the API.

```bash
cat > credentials.tfrc.json <<EOF
{
  "credentials": {
    "api.firefly.ai": {
      "token": "$TOKEN"
    }
  }
}
EOF
```

***

## Step 4 — Tell Terraform where the credentials file is

Terraform does **not** automatically look for a `credentials.tfrc.json` in your project directory. A file of that name only has meaning at Terraform's well-known credentials location. Choose one of the following.

### Option A — Point Terraform at the local file (recommended)

Set `TF_CLI_CONFIG_FILE` to the file you created in Step 3. This keeps the token scoped to the project directory and is ideal for CI pipelines and ephemeral environments:

```bash
export TF_CLI_CONFIG_FILE="$PWD/credentials.tfrc.json"
```

Set it once per shell session; every subsequent `terraform` command in that shell will find the token.

### Option B — Install it globally

Place the credentials at Terraform's default location so that a bare `terraform init` works from any directory, with no environment variable:

```
~/.terraform.d/credentials.tfrc.json
```

The file uses the exact same JSON structure as in Step 3:

```json
{
  "credentials": {
    "api.firefly.ai": {
      "token": "YOUR_TOKEN"
    }
  }
}
```

Remember to `chmod 600 ~/.terraform.d/credentials.tfrc.json`. If you already have other hosts in that file, add `api.firefly.ai` alongside them rather than overwriting it.

### Option C — Environment variable

Alternatively, skip the file entirely and provide the token through a host-specific environment variable. Terraform maps the host into the variable name by replacing dots with underscores:

```bash
export TF_TOKEN_api_firefly_ai="$TOKEN"
```

This is convenient in CI, though the credentials file (Option A) is generally less error-prone.

***

## Step 5 — Configure the `cloud {}` block

In your root module (for example `main.tf`), add a `cloud {}` block inside `terraform {}`:

```hcl
terraform {
  cloud {
    hostname     = "api.firefly.ai"             # Firefly API host
    organization = "FIREFLY_ACCOUNT_ID"       # your Firefly account ID
    workspaces {
      name = "WORKSPACE_NAME"                 # the name shown in the console
    }
  }
}

# ...your resources below...
```

* **`hostname`** is always `api.firefly.ai`.
* **`organization`** is your 24-character Firefly **account ID** — not a display name.
* **`workspaces.name`** is the exact name that will appear in the Firefly console.

> **Note:** assigning a new workspace to a specific project through the `cloud {}` block is not currently supported. Workspaces created this way are placed in your account's default (root) project. Do not set a `project` attribute inside `workspaces {}`.

***

## Step 6 — Initialize, plan, and apply

```bash
terraform init
```

On the first `init`, Terraform contacts Firefly, authenticates with your token, and — if the named workspace does not yet exist — Firefly **creates it automatically** as a state-only workspace (execution mode `local`, no VCS repository attached). The workspace appears in the console immediately, before any apply.

```bash
terraform plan     # reads your remote state, computes the diff locally
terraform apply    # acquires the state lock, uploads a new state version, releases the lock
```

`plan` and `apply` run entirely on your machine. On a successful `apply`, Terraform uploads the resulting state to Firefly and increments the workspace's state version (its serial number).

If `init` fails with **`Required token could not be found`**, Terraform is not seeing your credentials — revisit Step 4. (Do not run `terraform login`; it does not apply to Firefly.)

***

## Step 7 — View the workspace in the console

Open the Firefly console and go to **Workflows → Workspaces**. Your workspace — named exactly as you set it in Step 5 — is listed. Open it to see its current state version, serial, and last-updated time.

***

## Managing and removing a workspace

To tear down the infrastructure and remove the workspace:

```bash
terraform destroy
```

Then delete the workspace itself, either from the UI or via the API. Deletion is **by workspace ID**:

```bash
curl -X DELETE \
  -H "Authorization: Bearer $TOKEN" \
  "https://api.firefly.ai/v2/workspaces/<WORKSPACE_ID>"
```

You can find the workspace ID by resolving the workspace by name through the API.

***

## Security and token lifecycle

Treat the minted token like any long-lived secret:

* **Deleting an access key does not revoke tokens already minted from it.** A token is validated by its signature and expiry; the access key is consulted only when a *new* token is minted, never on a per-request basis. An already-issued token therefore remains valid until it expires, even after you delete the key it came from.
* **Prefer short durations and rotate.** Minting a fresh token is cheap. Favor short-lived tokens over a single long-lived one wherever your workflow allows.
* **Store tokens in a secrets manager**, never in source control, and restrict file permissions (`chmod 600`) on any credentials file.
* **If a token leaks, deleting the key is not sufficient** — because existing tokens stay valid until expiry, a leaked long-lived token is exposed for its full lifetime. This is the strongest reason to keep durations short.

***

## Troubleshooting

| Symptom                                       | Likely cause                                                   | Fix                                                                                                                   |
| --------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `Required token could not be found` on `init` | Terraform can't find the credentials                           | Apply Step 4 (`TF_CLI_CONFIG_FILE`, the global file, or `TF_TOKEN_api_firefly_ai`). Do **not** run `terraform login`. |
| `unauthorized` / HTTP 401 on `init`           | Token expired or wrong key pair                                | Re-mint the token (Step 2) and refresh your credentials file                                                          |
| Workspace does not appear in the console      | `organization` set to a display name instead of the account ID | Use your 24-character account ID                                                                                      |
| `init` cannot reach the host                  | Wrong or unreachable `hostname`                                | Confirm the host is `api.firefly.ai` and reachable from your network                                                  |
| Terraform errors when a `project` is set      | Project assignment via `cloud {}` is not supported             | Remove the `project` attribute from `workspaces {}`                                                                   |

***

## Quick reference

| Item                      | Value                                                           |
| ------------------------- | --------------------------------------------------------------- |
| API host                  | `api.firefly.ai`                                                |
| Token endpoint            | `POST https://api.firefly.ai/v2/login`                          |
| Login request body        | `{ "accessKey", "secretKey", "duration" }`                      |
| Login response fields     | `accessToken`, `expiresAt`, `tokenType`                         |
| `duration` format         | `<number><unit>` — `h`/`d`/`w`/`m`/`y`; default `24h`; max `1y` |
| Credentials file (local)  | pointed to by `TF_CLI_CONFIG_FILE`                              |
| Credentials file (global) | `~/.terraform.d/credentials.tfrc.json`                          |
| Env-var alternative       | `TF_TOKEN_api_firefly_ai`                                       |
| Delete a workspace        | `DELETE https://api.firefly.ai/v2/workspaces/<WORKSPACE_ID>`    |

***

## Related guides

* [Remote State Management](/detailed-guides/workflows/remote-state-management): Use Firefly as your backend with Firefly-managed or self-hosted runner execution (managed mode).
* [Firefly Workflows](/detailed-guides/workflows): High-level concepts, projects, and execution options.
* [Authentication](/general-information/api/auth): Creating API key pairs and minting tokens.
* [Access Management & RBAC](/getting-started/access-management-rbac): Managing keys, roles, and permissions.


# SSH Private Module Access

This guide walks you through configuring SSH-based access to private Git repositories containing Terraform modules, so they can be consumed by Firefly workspaces.

## Prerequisites

* A private Git repository containing a valid Terraform module.
* Access to the repository settings to add deploy keys.
* A Firefly workspace where the module will be consumed.
* An SSH key pair (public + private key) already generated and available for use.

***

## Step 1: Create a Deployment Key

A deploy key is an SSH key that grants access to a **single repository**. GitHub attaches the public part of the key directly to the repository (not to a personal account), while the private part remains on your server/CI environment.

Deploy keys are **read-only by default**, but you can optionally grant write access when adding them to the repository.

> For full details, see the official guides:
>
> * **GitHub:** [Managing deploy keys](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys)
> * **GitLab:** [Create a project deploy key](https://docs.gitlab.com/user/project/deploy_keys/#create-a-project-deploy-key)

### Important Considerations

* **One key per repository** — Each deploy key can only be used for a single repository. If you need to access multiple private module repos, generate a dedicated key pair for each one.
* **No passphrase by default** — Deploy keys are not protected by a passphrase, so if the key is compromised it can be used immediately. Store it securely.
* **Not linked to organization membership** — If the user who created the deploy key is removed from the repo, the key remains active.
* **No expiry date** — Deploy keys do not expire. Plan for periodic rotation.

***

## Step 2: Add the Public Key to the Repository

### GitHub

1. Navigate to the main page of the private module repository.
2. Go to **Settings** > **Deploy Keys** > **Add deploy key**.
3. In the **Title** field, provide a descriptive title (e.g., `firefly-workspace-module-access`).
4. In the **Key** field, paste the contents of `firefly_deploy_key.pub`.
5. **Do not** select "Allow write access" — read-only is sufficient for module fetching.
6. Click **Add key**.
7. Confirm the deploy key appears in the repository's Deploy Keys list.

> Deploy keys can also be created via the [GitHub REST API for deploy keys](https://docs.github.com/en/rest/deploy-keys).

### GitLab

1. Navigate to your project using the search bar at the top.
2. In the left sidebar, go to **Settings** > **Repository**.
3. Expand the **Deploy keys** section.
4. Click **Add new key**.
5. In the **Title** field, provide a descriptive title (e.g., `firefly-workspace-module-access`).
6. In the **Key** field, paste the contents of `firefly_deploy_key.pub`.
7. **Do not** select "Grant write permissions to this key" — read-only is sufficient for module fetching.
8. Optionally set an **Expiration date** for the key.
9. Click **Add key**.
10. Confirm the deploy key appears in the project's Deploy Keys list.

> Deploy keys can also be created via the [GitLab CLI](https://docs.gitlab.com/user/project/deploy_keys/#create-a-project-deploy-key) using `glab deploy-key add`.

***

## Step 3: Base64 Encode the Private Key

Encode the private key to base64 for safe storage as an environment variable:

```bash
cat firefly_deploy_key | base64 -w 0
```

Copy the resulting base64-encoded string. This value will be stored in Firefly in the next step.

***

## Step 4: Add the SSH Key as an Environment Variable in the Firefly Workspace

1. In the Firefly workspace, create a new environment variable with the following settings:

   | Field              | Value                                                                         |
   | ------------------ | ----------------------------------------------------------------------------- |
   | **Variable name**  | `SSH_PRIVATE_KEY`                                                             |
   | **Variable value** | The base64-encoded private key from Step 3                                    |
   | **Type**           | Environment Variable (not a Terraform variable)                               |
   | **Sensitive**      | Enabled — the value is write-only and will not be displayed in the UI or logs |
2. Confirm the variable appears in the workspace's variable list.

***

## Step 5: Configure Module Source

Push a Terraform configuration that references the private module via SSH:

```hcl
module "private_mod" {
  source = "git::ssh://git@github.com/org/private-module.git//subdir?ref=main"
}
```

The workspace will use the `SSH_PRIVATE_KEY` environment variable automatically during module initialization.

***

## Limitations

* **One SSH key per workspace** — Each workspace supports a single `SSH_PRIVATE_KEY` environment variable, which means only one private module repository can be accessed per workspace. If your Terraform configuration references multiple private modules from different repositories, they cannot all be served by the same SSH key.


# Codification

Firefly's Codification feature automatically converts existing cloud resources into Infrastructure-as-Code definitions. Generate Terraform, Pulumi, CloudFormation, and other IaC formats for resources created manually or lacking code management. This guide covers codification overview, supported formats, advanced features, and step-by-step usage.

## Overview

Codification transforms cloud and SaaS resources, on any provider Firefly supports, into the code needed to manage them going forward. While primarily used for unmanaged assets (resources created via ClickOps or outside of IaC), you can codify any asset regardless of its current IaC coverage. Firefly's scanner discovers all resources across cloud providers, SaaS platforms, and other supported services and can generate infrastructure-as-code representations for any of them. The goal is achieving 100% IaC coverage by generating code for everything running across your entire infrastructure estate.

Firefly generates comprehensive resource code that captures dependencies and configurations. When codifying an AWS EC2 instance, Firefly identifies related resources like attached EBS volumes, network interfaces, and security groups, including them in the code or referencing them appropriately. Similarly, when codifying SaaS resources like GitHub repositories or DataDog dashboards, Firefly captures their configurations, permissions, and relationships. This holistic approach ensures generated IaC is viable and complete across all provider types.

Codification is particularly valuable during infrastructure cleanup, onboarding phases, cloud migration, or when migrating between different IaC formats. When inheriting an environment with console-created resources across multiple providers, use Firefly to scan and generate Terraform automatically instead of manually writing code for each resource. You can also use codification to convert existing IaC-managed resources to different formats. For example, converting CloudFormation templates to Terraform or Pulumi code, or converting provider-specific configurations to cross-platform IaC. During cloud migration projects, codification helps capture the current state of resources in the source cloud and generate equivalent IaC definitions for the target cloud provider. Review, adjust, and commit the generated code to transform your entire infrastructure into your preferred code-managed format.

## Supported IaC Formats

Firefly supports codification to many Infrastructure-as-Code frameworks, allowing you to choose the format your team prefers:

* **Terraform/OpenTofu**: Generate HCL code (Terraform/OpenTofu configurations) as .tf files representing your resources, including Terraform modules, module calls.
* **Terraform CDK**: Generate CDK code in languages like TypeScript, Python and more to onboard resources into Terraform CDK stacks.
* **Terragrunt**: Generate Terragrunt code to onboard resources into Terragrunt stacks.
* **CloudFormation**: Generate AWS CloudFormation templates for AWS users relying on CloudFormation.
* **AWS CDK**: Generate AWS CDK code in languages like TypeScript, Python and more for programmatic IaC options on AWS. Supports both CDK level 1 and level 2.
* **Crossplane**: Output configurations for Crossplane, managing cloud resources as Kubernetes custom resources, including Crossplane Compositions.
* **Kubernetes Manifests**: Create raw Kubernetes manifests for Kubernetes resources.
* **Helm Charts**: Create Helm charts for Kubernetes resources.
* **CDK8s**: Generate CDK8s code in languages like TypeScript, Python and more to onboard Kubernetes resources into CDK8s stacks.
* **Config Connector**: Generate Google's Config Connector code for managing Google Cloud resources via Kubernetes CRDs.
* **ARM**: Generate Azure Resource Manager templates (ARM) for Azure users relying on ARM templates.
* **Bicep**: Generate Bicep code to onboard resources into Bicep stacks.
* **Ansible**: Generate Ansible playbook to onboard resources into Ansible.
* **Pulumi**: Output Pulumi code in supported languages like TypeScript, Python and more to onboard resources into Pulumi stacks.

Firefly meets you where you are, whether using Terraform, Pulumi, AWS CDK, or other frameworks, codification outputs appropriate files. Select your desired format when initiating codification. Each format has unique characteristics, Terraform uses specific naming conventions while Pulumi generates code in particular languages. Firefly abstracts these differences to provide ready-to-use definitions. After generation, integrate the code into your repositories or pipelines as needed.

## Advanced Codification Features

Beyond basic resource code generation, Firefly's codification offers advanced features for clean, maintainable and reusable IaC:

### Terraform/OpenTofu Dependency

Firefly detects relationship resources from the selected resource/s and codifies them together in one output. When you select an EC2 instance for codification, Firefly automatically identifies and includes related resources like VPC, subnet, security groups, and EBS volumes in the generated code. You can choose to either codify all resources (including those already managed by IaC) or use data blocks to reference existing resources that are already managed. This ensures the generated IaC is complete and deployable while respecting your existing infrastructure management approach.

> **Note**: For Azure, Firefly have an option to codify all resources in the resource group of the selected resource.

### Terraform/OpenTofu Module Creation

Convert resource groups into reusable Terraform/OpenTofu modules. Firefly intelligently packages selected resources and optionally with their dependencies, like VPCs with subnets and route tables, then generating a full module with all the resources and their dependencies including variables and outputs. This creates DRY (Don't Repeat Yourself) codified assets following modular IaC design best practices from the start.

### Terraform/OpenTofu Module Call

Codify unmanaged assets with an existing module. If you have an existing Terraform module for S3 buckets that your team uses, and you codify a bucket with the selected module, Firefly generates a module call filled with the correct parameters to incorporate the bucket into your existing module usage, ensuring consistency.

### Terraform/OpenTofu Cross-Cloud Migration

Once infrastructure is represented in code, migrate or replicate it to other cloud providers. Firefly aids cross-cloud migration by generating equivalent Terraform/OpenTofu IaC for different cloud providers. For example, when codifying an AWS EC2 instance, Firefly can generate the equivalent Azure VM or Google Cloud Compute Instance Terraform/OpenTofu configuration. This cross-cloud translation automatically maps resource types, properties, and configurations between providers while maintaining the same infrastructure intent.

### Crossplane Compositions

Convert resource groups into reusable Crossplane Compositions. Firefly intelligently packages selected resources, then generates a full Crossplane Composition with all the resources including CompositeResourceDefinitions (XRDs) and Composition configurations. This creates DRY (Don't Repeat Yourself) codified assets following modular Crossplane design best practices from the start.

### Auto-Detection: Karpenter-Managed EC2 Instances

Firefly automatically identifies AWS EC2 instances managed by [Karpenter](https://karpenter.sh/) and marks them as **codified** without requiring manual codification. This auto-detection works by inspecting the EC2 instance's tags.

For an `aws_instance` to be recognized by Firefly as managed via Karpenter, the EC2 instance must have a **tag key** that contains `karpenter.sh`.

**Examples of tags that will be recognized:**

| Tag Key                  | Tag Value         |
| ------------------------ | ----------------- |
| `karpenter.sh/discovery` | `backend-cluster` |
| `karpenter.sh`           | `backend-cluster` |
| `something-karpenter.sh` | `backend-cluster` |

**Example of a tag that will NOT be recognized:**

| Tag Key     | Tag Value                |
| ----------- | ------------------------ |
| `something` | `something-karpenter.sh` |

**Requirements:**

* The `karpenter.sh` string must appear in the **tag key**, not only in the tag value.
* The tag key must be **lowercase**.
* This auto-detection is currently implemented for **AWS EC2 instances** (`aws_instance`) only. It is not yet available for `google_compute_instance`, `azurerm_virtual_machine`, or `azurerm_linux_virtual_machine`.

Ensure your Karpenter-managed EC2 instances include a lowercase tag key containing `karpenter.sh` so Firefly can correctly classify them as codified. For Crossplane-managed resources, refer to the [External Resource Labeling](https://github.com/crossplane/crossplane/blob/main/design/one-pager-managed-resource-api-design.md#external-resource-labeling) design document for guidance on applying tags to managed resources.

These advanced features make codification an intelligent system producing high-quality IaC aligned with your best practices, not just a one-off script generator.

## Using Codification: Step-by-Step Guide

Follow these steps to effectively codify your infrastructure:

#### 1. Identify Resources to Codify

Navigate to the Inventory page in the Firefly app to find unmanaged assets. Filter by "Unmanaged" to see resources not currently managed by IaC. Select one or more resources you want to manage as code going forward.

> **Note**: You can codify resources that are already managed by IaC.

#### 2. Start the Codification Process

Select assets and click the "Codify" button. Choose your target IaC format (Terraform, Pulumi, etc.).

#### 3. Configure Output Options

Depending on your chosen format, select the codification type you want to use. For example, if you want to codify a resource group into a Terraform module, select "Create Module".

When codifying to Terraform/OpenTofu, you can also select the provider version for your data source (AWS, Azure, Google Cloud, etc.). By default, Firefly uses the latest version of the provider, but you can specify a particular version if your infrastructure requires it for compatibility or stability reasons.

#### 4. Generate IaC Code

Firefly will automatically generate the code and you can review the resulting code in the UI preview, checking resource names, parameters, and module structures. You can use the UI to edit the code before finalizing. Additionaly, you can use the AI chat to edit the code with Firefly's Thinkerbell AI assistant.

> **Note**: Sensitive data will not be included in the code. Edit the code to include the sensitive data as you see fit.

For Terraform/OpenTofu, Firefly automatically generates import blocks and commands alongside the resource definitions. These import statements allow you to bring existing resources under Terraform management without recreating them, ensuring zero downtime during the transition to IaC.

#### 5. Review Dependencies and Modules

If codification created multiple files, review the project structure. Ensure all necessary pieces are present. Files can be added/deleted/edited in the UI as you see fit.

#### 6. Export or Push the Code

Choose how to use the generated code:

* Download or copy to clipboard for manual integration.
* Create a Pull Request directly from the UI to your VCS repository.

#### 7. Implement the Code in Your Workflow

Merge the Pull Request or add code to your IaC repository. For Terraform/OpenTofu codification, Firefly provides both import commands and blocks, these import statements bring existing resources into your Terraform state without recreating them:

* **Import Blocks (Recommended)**: Modern Terraform versions support import blocks directly in your configuration files. Firefly generates these blocks automatically, allowing you to run `terraform plan` and `terraform apply` to import resources seamlessly.
* **Import Commands**: For older Terraform versions or manual workflows, Firefly provides the necessary `terraform import` commands to execute before applying your configuration.

After importing, run your standard IaC deployment process (terraform plan/apply, CloudFormation deployment, etc.). Since resources already exist and are now properly imported, Terraform will recognize them with correct IDs and settings, showing no changes needed on the first plan after import.

#### 8. Verify and Mark as Managed

After successful deployment, check Firefly's Inventory again. Previously unmanaged resources should now appear as Codified. Firefly detects when resources are represented in IaC state files, effectively transitioning them to code management.

> **Note**: In Firefly, it might take a few minutes to hours to detect the resources as IaC status change to "Codified".

#### 9. Repeat and Refine

Continue codifying other resources in batches by environment or resource type. As you gain more codified assets, your IaC coverage percentage increases and your cloud becomes more standardized. Leverage advanced features to modularize further or refactor generated code to suit your style.

#### 10. Leverage Automation (Optional)

Use Firefly's API for recurring changes. Set up automated workflows to codify new unmanaged assets and open PRs for review, ensuring your environment stays current in code. For more information, see [API Integration](/general-information/api).

#### 11. IDE Integration (Optional)

Use Firefly's MCP server with your IDE to enhance your development workflow. The Model Context Protocol (MCP) server allows you to interact with Firefly directly from your code editor, enabling you to:

* **Query cloud resources**: Ask questions about your infrastructure directly in your IDE.
* **Generate IaC code**: Create Terraform, Pulumi, or other IaC configurations without leaving your editor.

This integration streamlines the codification process by bringing Firefly's capabilities directly into your familiar development environment, making it easier to maintain consistency between your code and cloud infrastructure. For more information, see [MCP Integration](/integrations/mcp).

## Conclusion

Following these steps creates a smooth process for transforming "ClickOps" resources into code, resulting in maintainable, version-controlled infrastructure with reduced configuration drift and all IaC benefits (peer reviews, testing, rollback, etc.). Firefly accelerates your journey to full Infrastructure-as-Code, accomplishing in minutes what might otherwise take weeks of manual coding.


# IaC Explorer

The IaC Explorer in Firefly provides a comprehensive view of your Infrastructure-as-Code landscape across multiple IaC types. It allows you to analyze Terraform stacks, CloudFormation templates, Helm charts, and more IaC types in a unified interface. This centralized view is essential for platform engineers and DevOps teams to understand infrastructure composition, identify issues, and maintain governance across their IaC ecosystem.

## Supported IaC types

* **Terraform stacks** - Individual .tfstate files with their module composition.
* **OpenTofu stacks** - Individual .tfstate files with their module composition.
* **CloudFormation stacks** - AWS CloudFormation stacks.
* **Helm charts** - Kubernetes Helm charts deployments.
* **Kustomize manifests** - Kubernetes Kustomize manifests deployments.
* **ArgoCD applications** - ArgoCD applications deployments.

## Overview of IaC Explorer Tabs

The IaC Explorer is organized into several tabs, each focusing on different aspects of your infrastructure:

### Applied Stacks

The main view showing all your deployed infrastructure stacks with their current status, including:

* **Stack name** - The name of the stack.
* **IaC version** - The version of the IaC type used to deploy the stack.
* **IaC coverage** - The percentage of the stack that is covered by IaC and the status of the coverage.
* **Backend information** - Where state files are stored (S3, Terraform Cloud, etc.).
* **Data sources** - The data sources used to deploy the stack.
* **Last applied** - The date and time the stack was last applied.
* **Blast radius indicator** - Warning icon for stacks using outdated module versions.
* **Asset counts** - Number of resources managed by each stack with link directly to the inventory page filtered by the stack. The inventory page shows the resources that are managed by the stack.
* More information about the stack can be found in the Properties tab. View the stack content and additional details about the stack data sources and used resources that are not supported by Firefly.

#### Applied Stacks Use Cases

* **Infrastructure Oversight**: Monitor all deployed stacks across your organization from a single dashboard.
* **Drift Detection**: Identify stacks where live infrastructure differs from IaC definitions.
* **Change Impact Analysis**: Use blast radius indicators to understand which stacks are affected by outdated modules.
* **Compliance Auditing**: Track IaC coverage percentages to ensure infrastructure governance.
* **Troubleshooting**: Quickly identify unsynced stacks that need attention after module updates.
* **Resource Planning**: View asset counts and resource distribution across environments.
* **State Management**: Monitor backend health and last application times for each stack.

### Providers

Shows all Infrastructure-as-Code providers used across your environment:

* **Terraform and OpenTofu providers** - AWS, Azure, Google Cloud, etc.
* **Registry URLs** - Links to provider documentation and source.
* **Integration status** - Whether providers are properly integrated.
* **State file counts** - Number of state files using each provider with link directly to the stacks tab filtered by the provider.

#### Providers Use Cases

* **Integration Health**: Monitor provider connectivity and integration status.
* **Architecture Planning**: Understand multi-cloud footprint and provider distribution.

### Backends

Displays state storage backends and their configurations:

* **Remote state locations** - S3 buckets, Terraform Cloud, etc.
* **Backend name** - The name of the backend.
* **Stack counts** - Number of stacks using each backend with link directly to the stacks tab filtered by the backend.
* **Last scan** - When backends were last synchronized.
* **Settings menu** - Configure the backend settings:
  * **Exclude state files** - Exclude state files from being ingested by Firefly.
  * **GCS encryption** - Set the GCS encryption key on encrypted GCS backends.

#### Backends Use Cases

**State Management Strategy**: Monitor distribution of state files across backends.

### Modules

Comprehensive view of all Terraform and OpenTofu modules in use:

* **Module name** - The directory name of the module in the repository.
* **Module sources** - Registry modules, Git repositories.
* **Version** - Current versions.
* **Last contributor** - The last contributor to the module.
* **Misconfigurations** - Policy violations for the module.
* **Last updated** - When the module was last updated.
* **Usage** - How many stacks use each module with link directly to the stacks tab filtered by the module.
* **Blast radius indicator** - Warning icon for modules used by outdated stacks that use older versions of the module.

#### Modules Use Cases

* **Version Management**: Track module versions and identify outdated implementations.
* **Impact Analysis**: Use blast radius indicators to understand which stacks are affected by module updates.
* **Security Scanning**: Identify modules with known vulnerabilities or misconfigurations.
* **Code Reusability**: Monitor module adoption rates and identify reusable patterns.
* **Change Management**: Plan module updates and understand downstream impacts.
* **Quality Assurance**: Review module sources and ensure approved registries are used.

> **Tip:** To scan modules from non-default branches in Azure DevOps repositories, configure custom branch scanning in your integration settings. See [Azure DevOps — Scan Custom Branches for Modules](/integrations/version-control/azuredevops#scan-custom-branches-for-modules).

### Repositories

Shows all connected version control repositories:

* **VCS integration** - GitHub, GitLab, Bitbucket, etc.
* **Repository name** - The name of the repository.
* **Modules count** - Number of modules in the repository with link directly to the modules tab filtered by the repository.
* **Resources count** - Number of resources in the repository with link directly to the inventory page filtered by the repository.
* **Last scan** - When the repository was last scanned.

#### Repositories Use Cases

* **Source Control Oversight**: Monitor all repositories containing infrastructure code.
* **Content Analysis**: Understand the distribution of modules and resources across repositories.

## Navigating Applied Stacks

When you open the IaC Explorer page, you'll see a list of your integrated IaC stacks (for example, each Terraform .tfstate file that Firefly has ingested from your environment). Each stack represents a deployed infrastructure state. By selecting a stack, the Explorer will display its contents in an organized manner. The view will show the root module of the Terraform stack and any child modules that are being used.

In the Explorer interface, you can expand the hierarchy. For instance, the root of the stack might have several module calls (Terraform modules invoked by your configuration). You can click the **+** or expansion arrow next to a module call to drill down. This will show you the resources and sub-modules inside that module. The Explorer essentially lets you traverse the module tree of your Terraform configuration.

## Advanced Filtering and Search

The IaC Explorer includes powerful filtering capabilities to help you focus on specific infrastructure components:

### Filter Options

* **IaC Status** - Filter by managed, unmanaged, ghost, or modified resources.
* **Data Source** - Filter by specific cloud providers or integrations.
* **Data Source Status** - Show only integrated or pending integrations.
* **Backend** - Filter by state storage location.
* **Asset Type** - Focus on specific resource types (EC2 instances, S3 buckets, etc.).
* **Repository** - Filter by source code repository.
* **TF Versions** - Filter by Terraform version compatibility.
* **Providers** - Filter by specific provider types (AWS, Azure, etc.).
* **Modules** - Filter by module usage.
* **Sync Status** - Filter to show only *Unsynced* stacks in the Applied Stacks tab.
* **Application Status** - Filter to show only *Partially Applied* modules in the Modules tab.

### Search Functionality

Use the search bar to quickly find specific stacks or modules by name. The search supports partial matching and works across all tabs.

## Sync Status and Blast Radius Management

The IaC Explorer provides advanced capabilities to track module synchronization and understand the impact of changes across your infrastructure through sync status indicators with blast radius analysis.

When modules in your integrated Git repositories are updated but the corresponding state files haven't been updated to reflect these changes, Firefly helps you identify and address these discrepancies:

### Stack-Level Sync Status

* **Unsynced Status**: Stacks are marked as *Unsynced* in the Applied Stacks tab when their state files haven't been updated after module changes.
* **Visual Indicators**: Clear status icons and labels help you quickly identify problematic stacks.
* **Hover Details**: Hovering over the *Unsynced* status reveals Which modules are not up-to-date in the state.
* **Navigation Links**: Clicking on the *Unsynced* status redirects you to the Modules tab, filtered to show only the outdated modules used by that stack.

### Module-Level Application Status

* **Partially Applied Status**: Modules are marked as *Partially Applied* in the Modules tab when they've been updated but not all dependent stacks have been updated.
* **Impact Visibility**: Shows which state files are using outdated versions of the module.
* **Hover Details**: Hovering over the *Partially Applied* status displays Names of state files that haven't been updated.
* **Cross-Navigation**: Clicking on the *Partially Applied* status redirects you to the Applied Stacks tab, filtered to show only the unsynced stacks using that module.

### Best Practices for Sync and Blast Radius Management

#### Regular Monitoring

* **Daily Reviews**: Check for unsynced stacks as part of daily operations.
* **Weekly Planning**: Use blast radius analysis for weekly change planning sessions.
* **Pre-deployment Checks**: Always review sync status before major deployments.

#### Change Management Process

1. **Impact Assessment**: Use blast radius indicators to understand change scope.
2. **Staged Rollouts**: Apply module updates gradually based on blast radius information.
3. **Validation**: Monitor sync status to ensure all intended changes are applied.

This comprehensive sync status and blast radius functionality ensures that your infrastructure changes are well-coordinated, properly applied, and their impacts are clearly understood across your entire IaC ecosystem.

## Export and Reporting

The IaC Explorer provides export functionality for reporting and analysis, download filtered data as CSV or JSON.

## Best Practices for Using IaC Explorer

### Regular Monitoring

* **Weekly reviews** - Check for new drift or outdated modules.
* **Filter by status** - Focus on drifted stacks.
* **Track integration health** - Ensure all backends are properly connected.

### Governance and Compliance

* **Module standardization** - Identify stacks using non-approved modules.
* **Security scanning** - Review misconfigurations and vulnerabilities in modules.

## Conclusion

The IaC Explorer serves as your central command center for Infrastructure-as-Code management, providing the visibility and tools needed to maintain a well-governed, secure, and efficient infrastructure ecosystem across multiple technologies and cloud providers.


# Event Center

Firefly's Event Center provides a centralized and chronological view of all cloud events, including mutations, ClickOps events and CLI/SDK events. By consolidating scattered event data into a unified interface, the Event Center enhances investigation workflows, enables efficient issue tracking, and improves visibility into changes across cloud environments.

Think of the Event Center as an audit log for your cloud: it's where you go to answer "What happened recently in my infrastructure?".

## Overview

The Event Center presents a chronological log of events across your integrated cloud accounts. Each event corresponds to a change in an asset's state, displayed in a timeline and table format where each entry includes details like timestamp, asset affected, type of change, source of change, and the actor who made the change.

This gives you a unified history of infrastructure changes across both ClickOps (manual changes) and IaC-driven changes.

### Key Benefits

* **Enhanced User Experience**: Users can easily access a chronological list of cloud events for efficient tracking and issue resolution.
* **Improved Troubleshooting**: Helps trace the chain of events that led to cloud mutations, drifts, or unmanaged assets due to ClickOps.
* **Real-time Visibility**: Events are updated in near real-time as Firefly listens to cloud events (AWS CloudTrail, Azure Activity Logs, etc.) and IaC tool events.
* **Comprehensive Audit Trail**: Complete visibility into your cloud's evolution with attribution to specific users or processes.

## Event Types

The Event Center currently supports the following event types:

### ClickOps Events

Identifies manual changes made directly in cloud consoles, not managed by Infrastructure as Code (IaC). These events help track unauthorized or out-of-process changes that could lead to configuration drift.

When someone manually opens the AWS console and changes an S3 bucket setting, Firefly logs a ClickOps event noting that the bucket's configuration was altered. These entries are often highlighted since unmanaged changes are important to address quickly.

### CLI/SDK Events

Identifies changes made through CLI/SDK tools, such as AWS CLI, Azure CLI, automated scripts, etc. These events help track changes made through these tools.

When a user runs `aws s3 mb s3://my-bucket`, Firefly logs a CLI/SDK event noting that the bucket was created.

### Mutation Events

Tracks configuration changes to cloud assets, whether from manual changes, automated processes, or IaC deployments. Mutation events include detailed information about what changed, providing before and after configuration states like a code diff.

If a Terraform apply changes configuration of 5 resources, you'll see 5 mutation events for those changes. If a CI/CD pipeline or auto-scaling event occurs, those changes are also captured as mutation events.

## Capabilities

### Filtering Options

Users can filter events based on multiple criteria to drill down into specific changes:

* **Event Type**: Filter by Mutations, ClickOps, CLI/SDK events, or other event categories.
* **Action Type**: Filter by create, update, delete, etc.
* **Data Source**: Filter by cloud provider (AWS, GCP, Azure, etc.) as categorized in Inventory.
* **Location**: Region-based filtering to focus on specific geographical areas.
* **Asset Type**: Filter by resource types such as EC2 instances, S3 buckets, RDS databases, etc.
* **Owner**: Track events by the user responsible for changes.
* **Timeframe**: Choose from predefined options:
  * 24 hours (default)
  * 7 days
  * 30 days
  * Custom date ranges

### Search and Investigation

The Event Center provides powerful search capabilities to help you investigate specific issues:

* **Free-text search** across event details.
* **Asset-specific filtering** to track changes to particular resources.
* **Timeline navigation** to understand the sequence of events.
* **Export to CSV/JSON**: Export all filtered events for external analysis, reporting, or integration with other tools.

## Data Integration

The Event Center consolidates event data from multiple sources, providing comprehensive metadata for each event type:

### ClickOps & CLI/SDK Events Metadata

Each ClickOps and CLI/SDK event includes the following detailed information:

* **Date**: Exact timestamp of the event.
* **Event ID**: Unique identifier linked to cloud audit logs (e.g., AWS CloudTrail) for detailed investigation.
* **Event Name**: Description of the specific action performed.
* **Region**: Geographic location where the change occurred.
* **Service**: The cloud service involved (e.g., EC2, S3, IAM).
* **Owner**: The user or role responsible for the change.
* **Source IP**: The IP address from which the change was initiated.
* **User Agent**: Information about the client used to make the change.
* **Request Parameters**: Details of what was requested.
* **Response Elements**: Information about the cloud provider's response.
* **TLS Details**: Security-related information about the connection.

### Mutation Events Metadata

Each mutation event captures comprehensive change information:

* **Date**: When the change occurred.
* **Data Source**: The cloud provider or system where the change happened.
* **Location**: Region or zone information.
* **Asset Type**: The type of resource that changed.
* **Asset Name**: The specific resource identifier.
* **Before/After Configuration States**: Detailed configuration diff showing exactly what changed, similar to a code diff.

## Integration with Notifications & Alerting

To ensure you don't miss critical events, the Event Center integrates with external logging and alerting systems. For the full configuration details, see the [Notifications](broken://pages/fK1QFjrKh9Y4YrQvivAl) guide.

## Best Practices

### Daily Operations

* Review the Event Center daily to stay aware of infrastructure changes.
* Set up alerts for unexpected manual changes in production environments.
* Use filtering to focus on specific resources or timeframes during investigations.

### Compliance and Auditing

* Track the ratio of IaC vs. manual changes to measure infrastructure maturity.
* Use ownership information for post-incident analysis and accountability.

### Troubleshooting

* Correlate events with system issues to understand root causes.
* Use before/after configuration states to quickly identify problematic changes.
* Follow the event timeline to understand the sequence of changes leading to issues.

The Event Center transforms chaotic change management into an organized, auditable process that's essential for both reliability and security. By providing complete visibility into your cloud's evolution with proper attribution and integration capabilities, it serves as your single source of truth for infrastructure changes.


# Deny Events

Firefly's Deny Events surface cloud actions that were **blocked by governance policies** — such as AWS Service Control Policies (SCPs), Azure Policy denials, and GCP Organization Policy constraints. By consolidating these denied actions into the Event Center, Firefly gives you a clear view of *who* tried to do *what*, *which policy blocked it*, and *how to remediate it*.

Think of Deny Events as a window into your guardrails in action: it's where you go to answer "What did my policies just stop, and was that the right call?".

## Overview

Deny Events are a dedicated category within the [Event Center](/detailed-guides/event-center). Each entry corresponds to a cloud API action that was rejected by an organizational governance policy, displayed in the same chronological timeline as other events. Entries include details like timestamp, the principal who attempted the action, the target asset, the action attempted, and — where available — the specific policy that caused the denial.

This gives you a unified view of policy enforcement across AWS, Azure, and GCP, helping you tell apart legitimate guardrail hits from misconfigured policies that are blocking valid work.

### Key Benefits

* **Policy Visibility**: See exactly which SCP, Azure Policy, or GCP Org Policy constraint blocked a given action — no more digging through provider consoles.
* **Faster Troubleshooting**: When a developer reports "I can't do X", trace the denial straight to the responsible policy.
* **Misconfiguration Detection**: Spot policies that are too broad or incorrectly scoped by reviewing the actions they're blocking.
* **Compliance Evidence**: Demonstrate that your preventative guardrails are actively enforcing intended controls.
* **AI-Powered Remediation**: Get contextual recommendations directly inside the Event Center to resolve denials safely.

## Supported Providers

Firefly currently supports Deny Events from the following sources:

### AWS — Service Control Policies (SCPs)

Captures actions denied by SCPs attached to AWS Organizations, OUs, or accounts. SCPs operate at the organizational level and block API calls before they reach the target service, regardless of the principal's IAM permissions.

When a user or role attempts an action that violates an SCP — for example, creating an EC2 instance in a restricted region — Firefly logs a Deny Event with the denied action, the principal, and the target resource.

### Azure — Azure Policy

Captures actions denied by Azure Policy assignments with `deny` effect, applied at management group, subscription, or resource group scope.

For Azure, Firefly enriches the displayed event with additional details parsed from the raw event payload, including:

* **Policy Name**: The human-readable name of the Azure Policy definition that triggered the denial.
* **Policy Assignment**: The specific assignment (and scope) responsible for the block.
* **Redirect to Policy**: A direct link from the event to the policy definition in the Azure portal, so you can review and adjust it in context.

### GCP — Organization Policy Constraints

Captures actions denied by GCP Organization Policy constraints (both predefined boolean/list constraints and custom constraints). Firefly surfaces the constraint that blocked the action and, where available, the policy bindings responsible.

## Capabilities

### Filtering Deny Events

Deny Events appear alongside other Event Center entries and can be isolated using the **Event Type** filter set to *Deny*. They can be further refined using the standard Event Center filters:

* **Data Source**: Narrow to AWS, Azure, or GCP.
* **Action Type**: Focus on denied creates, deletes, updates, etc.
* **Asset Type**: Investigate denials against specific resource types.
* **Owner / Principal**: See which user, role, or service account was blocked.
* **Location**: Filter by region or scope.
* **Timeframe**: 24 hours, 7 days, 30 days, or a custom range.

### AI Recommendations

Each Deny Event includes an **AI Recommendation** panel below the event details. The recommendation analyzes the denied action together with the responsible policy and surfaces:

* **Policy Identification**: Which policy or constraint caused the denial, summarized in plain language.
* **Root Cause Explanation**: Why the action was blocked, including the conditions or scope that triggered the deny.
* **Suggested Remediation**: Concrete next steps — for example, adjusting the policy scope, exempting a specific principal, or modifying the offending request — so you can either unblock legitimate work or confirm the deny was correct.

The recommendation is contextual to the specific event and provider, and is generated on demand from the event's raw payload and the associated policy definition.

## Event Metadata

Each Deny Event includes the following information:

* **Date**: Timestamp of the denied attempt.
* **Provider**: AWS, Azure, or GCP.
* **Principal / Owner**: The user, role, or service account that attempted the action.
* **Action**: The specific API operation that was denied (e.g., `ec2:RunInstances`, `Microsoft.Storage/storageAccounts/write`).
* **Target Asset**: The resource the action was attempted against, where identifiable.
* **Region / Scope**: Where the attempt occurred.
* **Source IP / User Agent**: Origin of the request (where provided by the cloud provider).
* **Policy Details** *(Azure; AWS & GCP where available)*: Name and identifier of the policy that triggered the denial, plus a redirect link to the policy in the provider console.
* **Raw Event Payload**: The underlying cloud audit log entry for deeper investigation.

## Best Practices

### Daily Operations

* Review Deny Events alongside other Event Center activity to catch policy misconfigurations early.
* Investigate repeated denials from the same principal — they often indicate either a missing exemption or an attempted misuse.

### Policy Tuning

* Use the AI Recommendation to decide whether a deny is correct or whether the policy needs to be scoped more narrowly.
* Track denial patterns over time to identify policies that block more legitimate work than malicious activity.

### Compliance and Auditing

* Export filtered Deny Events for evidence that preventative guardrails are active and enforcing.
* Correlate denials with change requests to demonstrate that out-of-policy actions are being stopped before impact.

Deny Events turn silent policy denials into a visible, actionable signal — making your preventative controls observable, debuggable, and easier to evolve over time.


# AgentOps Events

Firefly's AgentOps Events surface cloud actions performed by **AI agents** — a third class of cloud operator alongside ClickOps (manual changes) and IaC. By classifying agent-driven activity as a first-class event source within the Event Center, Firefly gives you a clear view of *which agent* did *what*, *where*, and *why*.

Think of AgentOps Events as the audit trail for your automation: it's where you go to answer "What did agent X do in the last 24 hours?" without spelunking through CloudTrail.

## Overview

AgentOps Events are a dedicated source type within the [Event Center](/detailed-guides/event-center). Each entry corresponds to an operational action performed by an AI agent — for example, an AWS DevOps Agent, an automation service principal, or an Azure MCP Server-originated call — displayed in the same chronological timeline as ClickOps, CLI/SDK, and Mutation events. Entries include details like timestamp, the agent that acted, the target asset, the action taken, and an AI-generated summary of what happened.

This gives you a unified view of AI-driven operational activity across your environments, so you can tell apart routine automated work from unexpected agent behavior — all in the same place you already track human-driven and IaC-driven changes.

### Key Benefits

* **Centralized Operational Visibility**: Monitor AI-driven operational activity from a single place across environments, accounts, and providers.
* **Faster Troubleshooting**: Investigate failures and unexpected agent behavior with enriched, contextual event details — no jumping between provider consoles.
* **Improved Governance & Transparency**: Gain clear visibility into automated operational actions and the decisions behind them, supporting audit and compliance needs.
* **Reduced Investigation Time**: Correlate agent events with adjacent operational signals (Mutations, ClickOps, CLI/SDK) to accelerate incident resolution.

## How Events Are Classified

Firefly identifies AgentOps activity at ingestion and tags the event with a dedicated `AgentOps` source type. Classification is based on identification patterns including:

* **Agent IAM principals** — recognized agent identities such as the AWS DevOps Agent.
* **Automation service principals** — service principals carrying an MCP / automation user-agent signature.
* **MCP Server-originated calls** — for example, calls originating from the Azure MCP Server.

Once classified, the event flows through the Event Center pipeline like any other source, enriched with an AI-generated summary describing what the agent did.

## Capabilities

### Filtering AgentOps Events

AgentOps Events appear alongside other Event Center entries and can be isolated using the **Source Type** filter set to *AgentOps*. They can be further refined using the standard Event Center filters:

* **Data Source**: Narrow to a specific cloud provider.
* **Action Type**: Focus on creates, updates, deletes, etc.
* **Asset Type**: Investigate agent activity against specific resource types.
* **Owner / Actor**: See which agent performed the action.
* **Location**: Filter by region or scope.
* **Timeframe**: 24 hours, 7 days, 30 days, or a custom range.

A dedicated **AgentOps** hero card on the Event Center landing page provides an at-a-glance entry point, and AgentOps events are marked with a distinct badge and icon in the event list so they're easy to spot.

### Investigating an Event

Selecting an AgentOps event opens a side panel with the context needed to investigate:

* **AI Summary**: A generated, human-readable description of what the agent did.
* **Actor**: The agent identity responsible for the action.
* **Source**: Marked as *AgentOps*.
* **Target asset and action**: The resource affected and the operation performed.

Use the timeline view to correlate the agent's activity with adjacent ClickOps, CLI/SDK, or Mutation events and understand the full sequence of changes.

## Best Practices

* Review AgentOps activity regularly to understand what your agents are doing in production.
* Use the AI summary as a starting point, then drill into the event details and timeline for root-cause analysis.
* Correlate AgentOps events with Mutation and ClickOps events to distinguish intended automation from unexpected behavior.
* Track the volume and outcomes of agent-driven actions as part of your operational governance.


# Backup and Disaster Recovery

Firefly's Backup and Disaster Recovery (DR) capabilities provide robust tools to safeguard your cloud infrastructure, enabling you to recover quickly from failures and prevent misconfigurations that could lead to outages. This guide details how to use Firefly to mitigate, diagnose, and recover from infrastructure failures, as well as how to proactively prevent them.

## Overview

Disaster recovery (DR) is the process of restoring your cloud environment to a healthy state after an incident such as accidental deletion, misconfiguration, or infrastructure failure. Firefly offers:

* **Rapid recovery tools for deleted or misconfigured assets.**
* **Comprehensive mutation logs and clickops events for root cause analysis.**
* **Proactive notifications and insights to prevent disasters.**
* **Automated backups and configuration history (coming soon).**

## DR Readiness: Building a Resilient Foundation

Before diving into recovery procedures, establishing proper disaster recovery readiness is crucial. Firefly provides three foundational capabilities that significantly enhance your DR posture: **Codification**, **Tagging**, and **Drift Management**. These practices ensure your infrastructure is well-documented, organized, and consistent—making recovery faster and more reliable when disasters strike.

### Codification: Your Infrastructure's Blueprint

**Why it matters for DR:** Infrastructure-as-Code (IaC) serves as the definitive blueprint of your environment. When disasters occur, having your entire infrastructure codified means you can recreate resources exactly as they were, with all configurations, dependencies, and relationships intact. Without codification, recovery often involves manual recreation, leading to inconsistencies, missing configurations, and extended downtime.

**How Firefly helps:** Firefly's Codification feature seamlessly converts existing cloud resources into Infrastructure-as-Code definitions across multiple formats (Terraform, Pulumi, CloudFormation, and more). This ensures that even resources created manually or through ClickOps are captured in code, providing complete infrastructure documentation for recovery scenarios.

**Key benefits for DR:**

* **Complete asset recreation:** Regenerate exact resource configurations during recovery.
* **Dependency mapping:** Automatically capture resource relationships and dependencies.
* **Version control:** Track infrastructure changes and revert to known-good states.
* **Consistency:** Ensure recovered infrastructure matches original specifications.

For detailed instructions on codifying your infrastructure, see [Codification](/detailed-guides/codification).

### Tagging: Organizing for Rapid Recovery

**Why it matters for DR:** Proper tagging strategies enable rapid identification and prioritization of critical resources during disaster scenarios. Tags help you quickly locate business-critical assets, understand resource ownership, and implement recovery procedures in the correct order based on business impact and dependencies.

**How Firefly helps:** Firefly's governance engine can enforce tagging policies across your entire infrastructure, ensuring consistent labeling practices. You can create policies that require specific tags (environment, criticality, owner, backup-schedule) and automatically remediate missing or incorrect tags.

**Key benefits for DR:**

* **Asset prioritization:** Quickly identify critical resources that need immediate recovery.
* **Ownership clarity:** Know who to contact for specific resources during incidents.
* **Environment segregation:** Separate production, staging, and development resources.
* **Backup scheduling:** Organize resources by backup requirements and retention policies.

Use Firefly's Policy & Governance features to implement and enforce tagging standards. For more information, see [Policy & Governance](/detailed-guides/policy-and-governance).

### Drift Management: Maintaining Configuration Integrity

**Why it matters for DR:** Configuration drift occurs when live infrastructure diverges from its IaC definition. During disaster recovery, drifted resources may not behave as expected, leading to failed recoveries or inconsistent environments. Maintaining alignment between code and cloud ensures predictable recovery outcomes.

**How Firefly helps:** Firefly continuously monitors your infrastructure for drift, comparing live resource configurations against their IaC definitions. When drift is detected, Firefly provides clear remediation options to either update the code to match the current state or reconcile the cloud resources to match the desired IaC configuration.

**Key benefits for DR:**

* **Predictable recovery:** Ensure recovered resources behave exactly as designed.
* **Configuration accuracy:** Maintain consistency between documentation and reality.
* **Reduced recovery time:** Eliminate surprises during critical recovery operations.
* **Compliance maintenance:** Keep security and compliance configurations intact.

For step-by-step drift remediation procedures, see [Remediating Drifted Assets](/detailed-guides/cloud-asset-inventory/remediating-drifts).

### Implementing DR Readiness

To establish strong DR readiness using Firefly:

1. **Start with Codification:** Use Firefly to codify all unmanaged resources, prioritizing critical systems first.
2. **Implement Tagging Policies:** Create and enforce consistent tagging standards across your infrastructure
3. **Monitor and Remediate Drift:** Set up drift alerts and establish regular remediation cycles.
4. **Test Recovery Procedures:** Regularly validate that your codified infrastructure can be successfully deployed in recovery scenarios.

## Recovering from Infrastructure Failure

When an infrastructure failure occurs, Firefly provides tools to help you diagnose, resolve, and recover. The recovery process depends on whether you know which asset caused the failure.

### Recovering Deleted Assets: When the Responsible Asset is Known

If you know which asset was deleted or misconfigured (e.g., a team member accidentally deleted a resource), you can restore it using Firefly's codification and GitOps integration.

**Procedure:**

1. **Click on Inventory > Deleted.**
   * This view lists all assets that have been deleted from your environment.
2. **Filter by Time Range.**
   * Use the filter to narrow down the list to the relevant time period.
3. **Select the Deleted Asset and Codify.**
   * Click on the asset that was deleted. Use the **Codify** action to generate the Infrastructure-as-Code (IaC) template for the asset.
4. **Create a Pull Request.**
   * Firefly will prompt you to select the appropriate repository and branch for your GitOps workflow. Submit a pull request to restore the asset via code.
5. **Review and Merge.**
   * Once reviewed and merged, your CI/CD pipeline will recreate the asset in your cloud environment.

> **Tip:** This process ensures that the restored asset is managed by code, reducing the risk of future drift or manual misconfiguration.

### Viewing Mutations & ClickOps Events: When the Responsible Asset is Unknown

If you do not know which asset caused the failure, use Firefly's mutation tracking to investigate recent changes and identify the root cause.

**Procedure:**

1. **Click on Event Center**
   * View all mutations and clickops events in your environment.
2. **Apply Filters**
   * Filter assets by data source, environment, account, and location to narrow your search.
3. **Review Mutation Log or ClickOps Event**
   * Click on an asset name to transfer to the asset page and open its mutation log to see a timeline of configuration changes.
4. **Codify Revision**
   * For any suspicious or recent change, select the revision date and use **Codify Revision** to generate the IaC template for that point in time.
5. **Revert via Pull Request**
   * Restore the asset to a previous configuration by submitting a pull request.

> **Tip:** Mutation logs and clickops events provide a detailed audit trail, including who made each change and what was modified, making root cause analysis straightforward.

## Preventing Misconfiguration and Reliability Risks

Proactive prevention is key to avoiding disasters. Firefly enables you to set up notifications and subscribe to insights that alert you to risky configurations or changes.

### Receiving Notifications on Asset Changes

Stay informed about changes in your infrastructure by subscribing to notifications. These alerts help you:

* Detect new drifts and clickops events.
* Monitor IaC deployment failures.
* Get alerts on policy and guardrail violations.

**How to Subscribe:**

* Go to **Settings > Notifications** in Firefly.
* Choose your preferred notification channels (Slack, Teams, email, etc.).
* Select which events or asset changes should trigger notifications (e.g., deletions, drifts, policy violations).

> **Tip:** Fine-tune your notification settings to avoid alert fatigue and focus on critical events.

For more information, check the [Notifications](broken://pages/fK1QFjrKh9Y4YrQvivAl) guide.

### Subscribing to Policy Checks for Reliability and Misconfiguration Prevention

Firefly Governance contains policy-driven checks that highlight risky configurations. Subscribing to these policies helps you proactively address issues before they lead to outages.

#### Example of Top 5 Policies to Reduce Disaster Risk:

1. **Reliability: K8s Deployments running containers without a configured CPU limit**
   * K8s Deployments running containers without a configured CPU limit are vulnerable to resource exhaustion and can lead to outages.
2. **Reliability: AWS Database Instances in a Single Availability Zone**
   * Databases in one zone are vulnerable to zone failures. Multi-AZ deployment is recommended for resilience.
3. **Reliability: AWS RDS Instance Without Deletion Protection**
   * Without deletion protection, accidental or automated deletions can cause permanent data loss.
4. **Reliability: AWS DynamoDB Tables Without Point-in-Time Recovery**
   * Enable point-in-time recovery to restore tables to any previous state and protect against data loss.
5. **Misconfiguration: AWS ELB/LB Without Access Logs Enabled**
   * Access logs are essential for troubleshooting, monitoring, and security analysis. Enable logging to maintain visibility.

**How to Subscribe:**

* Go to **Settings > Governance** in Firefly.
* Subscribe to the above policies and configure notification preferences.

> **Tip:** Regularly review policy recommendations and remediate flagged issues to maintain a resilient infrastructure.

## Summary

Firefly's backup and disaster recovery features empower you to:

* Rapidly recover from accidental deletions or misconfigurations.
* Investigate and revert problematic changes.
* Proactively prevent outages with real-time notifications and policy-driven insights.

By integrating these tools and practices into your operations, you can ensure your cloud environment remains resilient, auditable, and secure.


# Service Coverage

Firefly Applications Backup & DR captures continuous snapshots of your applications and the infrastructure they depend on, with full dependency graphs, and restores complete environments as Terraform code.

This page lists every resource type Firefly protects, by provider, with the matching Terraform resource name. Coverage expands continuously — if a resource type you need is missing, see [Contacting Support](/general-information/contacting-support).

{% tabs %}
{% tab title="AWS" %}
Firefly protects 176 resource types across 48 AWS services.

### Amazon API Gateway

| Resource                   | Terraform resource             | Status    |
| -------------------------- | ------------------------------ | --------- |
| HTTP APIs                  | `aws_apigatewayv2_api`         | Supported |
| API Gateway Rest API       | `aws_api_gateway_rest_api`     | Supported |
| API Gateway Domain Name    | `aws_api_gateway_domain_name`  | Supported |
| API Gateway VPC Link       | `aws_api_gateway_vpc_link`     | Supported |
| API Gateway API Key        | `aws_api_gateway_api_key`      | Supported |
| API Gateway Usage Plan     | `aws_api_gateway_usage_plan`   | Supported |
| API Gateway Authorizer     | `aws_api_gateway_authorizer`   | Supported |
| API Gateway Integration    | `aws_api_gateway_integration`  | Supported |
| API Gateway v2 Route       | `aws_apigatewayv2_route`       | Supported |
| API Gateway Stage          | `aws_api_gateway_stage`        | Supported |
| API Gateway v2 Stage       | `aws_apigatewayv2_stage`       | Supported |
| API Gateway v2 Integration | `aws_apigatewayv2_integration` | Supported |
| API Gateway v2 Authorizer  | `aws_apigatewayv2_authorizer`  | Supported |

### Amazon Aurora

| Resource                                        | Terraform resource         | Status    |
| ----------------------------------------------- | -------------------------- | --------- |
| Database Clusters (Provisioned & Serverless v2) | `aws_rds_cluster`          | Supported |
| RDS Cluster Instance                            | `aws_rds_cluster_instance` | Supported |
| DB Parameter Group                              | `aws_db_parameter_group`   | Supported |
| DB Subnet Group                                 | `aws_db_subnet_group`      | Supported |
| DB Proxy                                        | `aws_db_proxy`             | Supported |

### Amazon Certificate Manager (ACM)

| Resource     | Terraform resource    | Status    |
| ------------ | --------------------- | --------- |
| Certificates | `aws_acm_certificate` | Supported |

### Amazon Cloud Map

| Resource                  | Terraform resource                            | Status    |
| ------------------------- | --------------------------------------------- | --------- |
| Cloud Map Namespaces      | `aws_service_discovery_private_dns_namespace` | Supported |
| Service Discovery Service | `aws_service_discovery_service`               | Supported |

### Amazon CloudWatch

| Resource             | Terraform resource            | Status    |
| -------------------- | ----------------------------- | --------- |
| CloudWatch Alarms    | `aws_cloudwatch_metric_alarm` | Supported |
| CloudWatch Log Group | `aws_cloudwatch_log_group`    | Supported |

### Amazon Cognito

| Resource                  | Terraform resource              | Status    |
| ------------------------- | ------------------------------- | --------- |
| Cognito User Pools        | `aws_cognito_user_pool`         | Supported |
| Cognito User Pool Client  | `aws_cognito_user_pool_client`  | Supported |
| Cognito Identity Provider | `aws_cognito_identity_provider` | Supported |

### Amazon DocumentDB

| Resource               | Terraform resource           | Status    |
| ---------------------- | ---------------------------- | --------- |
| Database Clusters      | `aws_docdb_cluster`          | Supported |
| DocDB Cluster Instance | `aws_docdb_cluster_instance` | Supported |

### Amazon DynamoDB

| Resource        | Terraform resource   | Status    |
| --------------- | -------------------- | --------- |
| DynamoDB Tables | `aws_dynamodb_table` | Supported |

### Amazon ElastiCache

| Resource                      | Terraform resource                  | Status    |
| ----------------------------- | ----------------------------------- | --------- |
| Cache Clusters                | `aws_elasticache_cluster`           | Supported |
| ElastiCache Replication Group | `aws_elasticache_replication_group` | Supported |
| ElastiCache Parameter Group   | `aws_elasticache_parameter_group`   | Supported |
| ElastiCache Subnet Group      | `aws_elasticache_subnet_group`      | Supported |
| ElastiCache User              | `aws_elasticache_user`              | Supported |
| ElastiCache User Group        | `aws_elasticache_user_group`        | Supported |

### AWS Elastic Beanstalk

| Resource                                 | Terraform resource                             | Status    |
| ---------------------------------------- | ---------------------------------------------- | --------- |
| Elastic Beanstalk Applications           | `aws_elastic_beanstalk_application`            | Supported |
| Elastic Beanstalk Application Version    | `aws_elastic_beanstalk_application_version`    | Supported |
| Elastic Beanstalk Configuration Template | `aws_elastic_beanstalk_configuration_template` | Supported |
| Elastic Beanstalk Environment            | `aws_elastic_beanstalk_environment`            | Supported |

### Amazon FSx for NetApp ONTAP

| Resource                          | Terraform resource                      | Status    |
| --------------------------------- | --------------------------------------- | --------- |
| File Systems                      | `aws_fsx_ontap_file_system`             | Supported |
| FSx ONTAP Volume                  | `aws_fsx_ontap_volume`                  | Supported |
| FSx ONTAP Storage Virtual Machine | `aws_fsx_ontap_storage_virtual_machine` | Supported |

### Amazon FSx for Windows File Servers

| Resource     | Terraform resource            | Status    |
| ------------ | ----------------------------- | --------- |
| File Systems | `aws_fsx_windows_file_system` | Supported |

### Amazon OpenSearch

| Resource             | Terraform resource         | Status    |
| -------------------- | -------------------------- | --------- |
| OpenSearch Domains   | `aws_opensearch_domain`    | Supported |
| OSIS Pipeline        | `aws_osis_pipeline`        | Supported |
| Elasticsearch Domain | `aws_elasticsearch_domain` | Supported |

### Amazon Redshift

| Resource                      | Terraform resource                 | Status    |
| ----------------------------- | ---------------------------------- | --------- |
| Redshift Cluster              | `aws_redshift_cluster`             | Supported |
| Redshift Parameter Group      | `aws_redshift_parameter_group`     | Supported |
| Redshift Subnet Group         | `aws_redshift_subnet_group`        | Supported |
| Redshift Serverless Namespace | `aws_redshiftserverless_namespace` | Supported |
| Redshift Serverless Workgroup | `aws_redshiftserverless_workgroup` | Supported |

### Amazon Relational Database Service (RDS)

| Resource           | Terraform resource       | Status    |
| ------------------ | ------------------------ | --------- |
| Database Instances | `aws_db_instance`        | Supported |
| DB Option Group    | `aws_db_option_group`    | Supported |
| DB Parameter Group | `aws_db_parameter_group` | Supported |
| DB Subnet Group    | `aws_db_subnet_group`    | Supported |
| DB Proxy           | `aws_db_proxy`           | Supported |

### AWS Secrets Manager

| Resource | Terraform resource          | Status    |
| -------- | --------------------------- | --------- |
| Secrets  | `aws_secretsmanager_secret` | Supported |

### Amazon Simple Storage Service (S3)

| Resource                                       | Terraform resource                                   | Status    |
| ---------------------------------------------- | ---------------------------------------------------- | --------- |
| S3 Buckets                                     | `aws_s3_bucket`                                      | Supported |
| S3 Bucket Policy                               | `aws_s3_bucket_policy`                               | Supported |
| S3 Bucket Public Access Block                  | `aws_s3_bucket_public_access_block`                  | Supported |
| S3 Bucket Versioning                           | `aws_s3_bucket_versioning`                           | Supported |
| S3 Bucket Server Side Encryption Configuration | `aws_s3_bucket_server_side_encryption_configuration` | Supported |
| S3 Bucket Lifecycle Configuration              | `aws_s3_bucket_lifecycle_configuration`              | Supported |
| S3 Bucket Logging                              | `aws_s3_bucket_logging`                              | Supported |

### AWS Systems Manager

| Resource         | Terraform resource  | Status    |
| ---------------- | ------------------- | --------- |
| Parameter Values | `aws_ssm_parameter` | Supported |

### Amazon Elastic Compute Cloud (EC2)

| Resource              | Terraform resource         | Status    |
| --------------------- | -------------------------- | --------- |
| Amazon Machine Images | `aws_ami`                  | Supported |
| EBS Volume            | `aws_ebs_volume`           | Supported |
| Instance              | `aws_instance`             | Supported |
| Launch Configuration  | `aws_launch_configuration` | Supported |
| Security Group        | `aws_security_group`       | Supported |

### Amazon EC2 Auto Scaling

| Resource             | Terraform resource         | Status    |
| -------------------- | -------------------------- | --------- |
| Auto Scaling Group   | `aws_autoscaling_group`    | Supported |
| Launch Configuration | `aws_launch_configuration` | Supported |
| Auto Scaling Policy  | `aws_autoscaling_policy`   | Supported |
| Launch Template      | `aws_launch_template`      | Supported |

### Amazon Elastic Container Registry (ECR)

| Resource                    | Terraform resource                | Status    |
| --------------------------- | --------------------------------- | --------- |
| ECR Repositories            | `aws_ecr_repository`              | Supported |
| ECR Pull Through Cache Rule | `aws_ecr_pull_through_cache_rule` | Supported |

### Amazon Elastic Container Service (ECS)

| Resource              | Terraform resource          | Status    |
| --------------------- | --------------------------- | --------- |
| ECS Clusters          | `aws_ecs_cluster`           | Supported |
| ECS Service           | `aws_ecs_service`           | Supported |
| ECS Task Definition   | `aws_ecs_task_definition`   | Supported |
| ECS Task Set          | `aws_ecs_task_set`          | Supported |
| ECS Capacity Provider | `aws_ecs_capacity_provider` | Supported |

### Amazon Elastic File System (EFS)

| Resource         | Terraform resource     | Status    |
| ---------------- | ---------------------- | --------- |
| EFS File Systems | `aws_efs_file_system`  | Supported |
| EFS Access Point | `aws_efs_access_point` | Supported |
| EFS Mount Target | `aws_efs_mount_target` | Supported |

### Amazon Elastic Kubernetes Service (EKS)

| Resource                     | Terraform resource                 | Status    |
| ---------------------------- | ---------------------------------- | --------- |
| EKS Clusters                 | `aws_eks_cluster`                  | Supported |
| EKS Addon                    | `aws_eks_addon`                    | Supported |
| EKS Fargate Profile          | `aws_eks_fargate_profile`          | Supported |
| EKS Node Group               | `aws_eks_node_group`               | Supported |
| Kubernetes Namespace         | `kubernetes_namespace`             | Supported |
| EKS Identity Provider Config | `aws_eks_identity_provider_config` | Supported |

### Amazon Elastic Load Balancing (ELB)

| Resource                             | Terraform resource            | Status    |
| ------------------------------------ | ----------------------------- | --------- |
| Classic Load Balancers               | `aws_elb`                     | Supported |
| Application / Network Load Balancers | `aws_lb`                      | Supported |
| LB Target Group                      | `aws_lb_target_group`         | Supported |
| LB Listener                          | `aws_lb_listener`             | Supported |
| LB Listener Rule                     | `aws_lb_listener_rule`        | Supported |
| LB Listener Certificate              | `aws_lb_listener_certificate` | Supported |

### Amazon EventBridge

| Resource                 | Terraform resource             | Status    |
| ------------------------ | ------------------------------ | --------- |
| EventBridge Event Buses  | `aws_cloudwatch_event_bus`     | Supported |
| CloudWatch Event Rule    | `aws_cloudwatch_event_rule`    | Supported |
| Scheduler Schedule       | `aws_scheduler_schedule`       | Supported |
| Scheduler Schedule Group | `aws_scheduler_schedule_group` | Supported |
| CloudWatch Event Target  | `aws_cloudwatch_event_target`  | Supported |

### Amazon Firehose

| Resource         | Terraform resource                     | Status    |
| ---------------- | -------------------------------------- | --------- |
| Delivery Streams | `aws_kinesis_firehose_delivery_stream` | Supported |

### AWS Identity and Access Management (IAM)

| Resource                    | Terraform resource                | Status    |
| --------------------------- | --------------------------------- | --------- |
| IAM Roles                   | `aws_iam_role`                    | Supported |
| IAM Policy                  | `aws_iam_policy`                  | Supported |
| IAM Instance Profile        | `aws_iam_instance_profile`        | Supported |
| IAM Openid Connect Provider | `aws_iam_openid_connect_provider` | Supported |
| IAM User                    | `aws_iam_user`                    | Supported |
| IAM Group                   | `aws_iam_group`                   | Supported |
| IAM Group Membership        | `aws_iam_group_membership`        | Supported |
| IAM Access Key              | `aws_iam_access_key`              | Supported |
| IAM Role Policy             | `aws_iam_role_policy`             | Supported |
| IAM Role Policy Attachment  | `aws_iam_role_policy_attachment`  | Supported |

### AWS Key Management Service (KMS)

| Resource    | Terraform resource | Status    |
| ----------- | ------------------ | --------- |
| KMS Aliases | `aws_kms_alias`    | Supported |
| KMS Key     | `aws_kms_key`      | Supported |

### AWS Lambda

| Resource                    | Terraform resource                | Status    |
| --------------------------- | --------------------------------- | --------- |
| Lambda Functions            | `aws_lambda_function`             | Supported |
| Lambda Alias                | `aws_lambda_alias`                | Supported |
| Lambda Layer Version        | `aws_lambda_layer_version`        | Supported |
| Lambda Event Source Mapping | `aws_lambda_event_source_mapping` | Supported |
| Lambda Permission           | `aws_lambda_permission`           | Supported |

### Amazon Route 53

| Resource                               | Terraform resource                          | Status    |
| -------------------------------------- | ------------------------------------------- | --------- |
| Private Hosted Zones                   | `aws_route53_zone`                          | Supported |
| Route 53 Profiles Profile              | `aws_route53profiles_profile`               | Supported |
| Route 53 Resolver Endpoint             | `aws_route53_resolver_endpoint`             | Supported |
| Route 53 Resolver Rule                 | `aws_route53_resolver_rule`                 | Supported |
| Route 53 Resolver Firewall Domain List | `aws_route53_resolver_firewall_domain_list` | Supported |
| Route 53 Resolver Firewall Rule Group  | `aws_route53_resolver_firewall_rule_group`  | Supported |
| Route 53 Record                        | `aws_route53_record`                        | Supported |

### Amazon Simple Notification Service (SNS)

| Resource               | Terraform resource           | Status    |
| ---------------------- | ---------------------------- | --------- |
| SNS Topics             | `aws_sns_topic`              | Supported |
| SNS Topic Subscription | `aws_sns_topic_subscription` | Supported |

### Amazon Simple Queue Service (SQS)

| Resource   | Terraform resource | Status    |
| ---------- | ------------------ | --------- |
| SQS Queues | `aws_sqs_queue`    | Supported |

### AWS Transfer Family

| Resource          | Terraform resource      | Status    |
| ----------------- | ----------------------- | --------- |
| SFTP Servers      | `aws_transfer_server`   | Supported |
| Transfer User     | `aws_transfer_user`     | Supported |
| Transfer Ssh Key  | `aws_transfer_ssh_key`  | Supported |
| Transfer Workflow | `aws_transfer_workflow` | Supported |

### Amazon Virtual Private Cloud (VPC)

| Resource                               | Terraform resource                           | Status    |
| -------------------------------------- | -------------------------------------------- | --------- |
| DHCP Options                           | `aws_vpc_dhcp_options`                       | Supported |
| Internet Gateway                       | `aws_internet_gateway`                       | Supported |
| EC2 Managed Prefix List                | `aws_ec2_managed_prefix_list`                | Supported |
| NAT Gateway                            | `aws_nat_gateway`                            | Supported |
| Network ACL                            | `aws_network_acl`                            | Supported |
| Route Table                            | `aws_route_table`                            | Supported |
| Security Group                         | `aws_security_group`                         | Supported |
| Subnet                                 | `aws_subnet`                                 | Supported |
| EC2 Transit Gateway                    | `aws_ec2_transit_gateway`                    | Supported |
| EC2 Transit Gateway Peering Attachment | `aws_ec2_transit_gateway_peering_attachment` | Supported |
| EC2 Transit Gateway Route Table        | `aws_ec2_transit_gateway_route_table`        | Supported |
| EC2 Transit Gateway VPC Attachment     | `aws_ec2_transit_gateway_vpc_attachment`     | Supported |
| VPC                                    | `aws_vpc`                                    | Supported |
| VPC Endpoint                           | `aws_vpc_endpoint`                           | Supported |
| VPC Peering Connection                 | `aws_vpc_peering_connection`                 | Supported |
| EIP                                    | `aws_eip`                                    | Supported |
| Flow Log                               | `aws_flow_log`                               | Supported |

### AWS Web Application Firewall (WAF)

| Resource                | Terraform resource            | Status    |
| ----------------------- | ----------------------------- | --------- |
| Web ACLs                | `aws_wafv2_web_acl`           | Supported |
| WAFv2 IP Set            | `aws_wafv2_ip_set`            | Supported |
| WAFv2 Regex Pattern Set | `aws_wafv2_regex_pattern_set` | Supported |
| WAFv2 Rule Group        | `aws_wafv2_rule_group`        | Supported |

### AWS MSK

| Resource               | Terraform resource           | Status    |
| ---------------------- | ---------------------------- | --------- |
| Provisioned Clusters   | `aws_msk_cluster`            | Supported |
| MSK Serverless Cluster | `aws_msk_serverless_cluster` | Supported |

### AWS Step Functions

| Resource       | Terraform resource      | Status    |
| -------------- | ----------------------- | --------- |
| State Machines | `aws_sfn_state_machine` | Supported |
| SFN Alias      | `aws_sfn_alias`         | Supported |

### AWS Resource Access Manager

| Resource   | Terraform resource       | Status    |
| ---------- | ------------------------ | --------- |
| RAM Shares | `aws_ram_resource_share` | Supported |

### Amazon Bedrock

| Resource                                       | Terraform resource                                   | Status    |
| ---------------------------------------------- | ---------------------------------------------------- | --------- |
| Guardrails                                     | `aws_bedrock_guardrail`                              | Supported |
| Bedrock Model Invocation Logging Configuration | `aws_bedrock_model_invocation_logging_configuration` | Supported |

### Amazon GuardDuty

| Resource  | Terraform resource       | Status    |
| --------- | ------------------------ | --------- |
| Detectors | `aws_guardduty_detector` | Supported |

### AWS Network Firewall

| Resource  | Terraform resource             | Status    |
| --------- | ------------------------------ | --------- |
| Firewalls | `aws_networkfirewall_firewall` | Supported |

### AWS Glue

| Resource           | Terraform resource          | Status    |
| ------------------ | --------------------------- | --------- |
| Catalog Databases  | `aws_glue_catalog_database` | Supported |
| Glue Catalog Table | `aws_glue_catalog_table`    | Supported |
| Glue Crawler       | `aws_glue_crawler`          | Supported |
| Glue Job           | `aws_glue_job`              | Supported |
| Glue Connection    | `aws_glue_connection`       | Supported |

### Amazon Athena

| Resource           | Terraform resource       | Status    |
| ------------------ | ------------------------ | --------- |
| Workgroups         | `aws_athena_workgroup`   | Supported |
| Athena Database    | `aws_athena_database`    | Supported |
| Athena Named Query | `aws_athena_named_query` | Supported |

### Amazon Kinesis Data Streams

| Resource | Terraform resource   | Status    |
| -------- | -------------------- | --------- |
| Streams  | `aws_kinesis_stream` | Supported |

### Amazon EMR

| Resource | Terraform resource | Status    |
| -------- | ------------------ | --------- |
| Clusters | `aws_emr_cluster`  | Supported |

### Amazon Neptune

| Resource                 | Terraform resource             | Status    |
| ------------------------ | ------------------------------ | --------- |
| Clusters                 | `aws_neptune_cluster`          | Supported |
| Neptune Cluster Instance | `aws_neptune_cluster_instance` | Supported |

### AWS Global Accelerator

| Resource     | Terraform resource                  | Status    |
| ------------ | ----------------------------------- | --------- |
| Accelerators | `aws_globalaccelerator_accelerator` | Supported |
| {% endtab %} |                                     |           |

{% tab title="Azure" %}
Firefly protects 74 resource types across 14 Azure services.

### Azure Key Vault

| Resource     | Terraform resource              | Status    |
| ------------ | ------------------------------- | --------- |
| Vaults       | `azurerm_key_vault`             | Supported |
| Secrets      | `azurerm_key_vault_secret`      | Supported |
| Certificates | `azurerm_key_vault_certificate` | Supported |
| Keys         | `azurerm_key_vault_key`         | Supported |

### Azure Storage

| Resource         | Terraform resource          | Status    |
| ---------------- | --------------------------- | --------- |
| Storage Accounts | `azurerm_storage_account`   | Supported |
| Blob Containers  | `azurerm_storage_container` | Supported |
| Blobs            | `azurerm_storage_blob`      | Supported |
| Queues           | `azurerm_storage_queue`     | Supported |

### Azure VMs

| Resource                   | Terraform resource                                                                    | Status    |
| -------------------------- | ------------------------------------------------------------------------------------- | --------- |
| Virtual Machines           | `azurerm_linux_virtual_machine / azurerm_windows_virtual_machine`                     | Supported |
| Managed Disks              | `azurerm_managed_disk`                                                                | Supported |
| Virtual Machine Images     | `azurerm_image`                                                                       | Supported |
| Availability Sets          | `azurerm_availability_set`                                                            | Supported |
| Virtual Machine Scale Sets | `azurerm_linux_virtual_machine_scale_set / azurerm_windows_virtual_machine_scale_set` | Supported |
| Bastion Hosts              | `azurerm_bastion_host`                                                                | Supported |

### Virtual Networks

| Resource                               | Terraform resource                                                                                                   | Status    |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --------- |
| Virtual Networks                       | `azurerm_virtual_network`                                                                                            | Supported |
| Subnets                                | `azurerm_subnet`                                                                                                     | Supported |
| Route Tables                           | `azurerm_route_table`                                                                                                | Supported |
| Public IP addresses                    | `azurerm_public_ip`                                                                                                  | Supported |
| NAT Gateways                           | `azurerm_nat_gateway`                                                                                                | Supported |
| Network Interfaces                     | `azurerm_network_interface`                                                                                          | Supported |
| Application Security Groups            | `azurerm_application_security_group`                                                                                 | Supported |
| Network Security Groups                | `azurerm_network_security_group`                                                                                     | Supported |
| Private DNS Zones                      | `azurerm_private_dns_zone`                                                                                           | Supported |
| Private DNS Zone Record Sets           | `azurerm_private_dns_a_record / _aaaa_record / _cname_record / _mx_record / _ptr_record / _srv_record / _txt_record` | Supported |
| Private DNS Zone Virtual Network Links | `azurerm_private_dns_zone_virtual_network_link`                                                                      | Supported |
| Private DNS Zone Groups                | `private_dns_zone_group block of azurerm_private_endpoint`                                                           | Supported |
| Private Endpoints                      | `azurerm_private_endpoint`                                                                                           | Supported |
| Virtual Network Peerings               | `azurerm_virtual_network_peering`                                                                                    | Supported |

### Load Balancing

| Resource                         | Terraform resource                        | Status    |
| -------------------------------- | ----------------------------------------- | --------- |
| Azure Load Balancer              | `azurerm_lb`                              | Supported |
| Application Gateway              | `azurerm_application_gateway`             | Supported |
| Application Gateway WAF Policies | `azurerm_web_application_firewall_policy` | Supported |

### Azure SQL

| Resource                           | Terraform resource                                   | Status    |
| ---------------------------------- | ---------------------------------------------------- | --------- |
| SQL Servers                        | `azurerm_mssql_server`                               | Supported |
| SQL DB                             | `azurerm_mssql_database`                             | Supported |
| SQL Server Firewall Rules          | `azurerm_mssql_firewall_rule`                        | Supported |
| SQL Server Outbound Firewall Rules | `azurerm_mssql_outbound_firewall_rule`               | Supported |
| SQL Server Virtual Network Rules   | `azurerm_mssql_virtual_network_rule`                 | Supported |
| SQL Server Connection Policies     | `connection_policy argument of azurerm_mssql_server` | Supported |
| SQL Server DNS Aliases             | `azapi_resource (Microsoft.Sql/servers/dnsAliases)`  | Supported |
| SQL on VMs                         | `azurerm_mssql_virtual_machine`                      | Supported |

### Containers

| Resource               | Terraform resource                   | Status    |
| ---------------------- | ------------------------------------ | --------- |
| Container Instances    | `azurerm_container_group`            | Supported |
| Container Registries   | `azurerm_container_registry`         | Supported |
| Container Repositories | `data plane — no Terraform resource` | Supported |

### Identity / Authorization

| Resource                       | Terraform resource                      | Status    |
| ------------------------------ | --------------------------------------- | --------- |
| User-Assigned Identities       | `azurerm_user_assigned_identity`        | Supported |
| Federated Identity Credentials | `azurerm_federated_identity_credential` | Supported |
| Custom Role Definitions        | `azurerm_role_definition`               | Supported |
| Role Assignments               | `azurerm_role_assignment`               | Supported |

### Azure App Services

| Resource                   | Terraform resource                                            | Status    |
| -------------------------- | ------------------------------------------------------------- | --------- |
| Web Apps                   | `azurerm_linux_web_app / azurerm_windows_web_app`             | Supported |
| Function Apps              | `azurerm_linux_function_app / azurerm_windows_function_app`   | Supported |
| App Service Plans          | `azurerm_service_plan`                                        | Supported |
| App Service Certificates   | `azurerm_app_service_certificate`                             | Supported |
| App Service Environments   | `azurerm_app_service_environment_v3`                          | Supported |
| Web App Auth Settings      | `auth_settings / auth_settings_v2 block of azurerm_*_web_app` | Supported |
| Web App Host Name Bindings | `azurerm_app_service_custom_hostname_binding`                 | Supported |

### Azure Service Bus

| Resource                  | Terraform resource                            | Status    |
| ------------------------- | --------------------------------------------- | --------- |
| Namespaces                | `azurerm_servicebus_namespace`                | Supported |
| Queues                    | `azurerm_servicebus_queue`                    | Supported |
| Queue Authorization Rules | `azurerm_servicebus_queue_authorization_rule` | Supported |
| Subscriptions             | `azurerm_servicebus_subscription`             | Supported |
| Subscription Rules        | `azurerm_servicebus_subscription_rule`        | Supported |
| Topics                    | `azurerm_servicebus_topic`                    | Supported |
| Topic Authorization Rules | `azurerm_servicebus_topic_authorization_rule` | Supported |

### Azure Kubernetes Service (AKS)

| Resource                          | Terraform resource                     | Status    |
| --------------------------------- | -------------------------------------- | --------- |
| AKS Managed Clusters              | `azurerm_kubernetes_cluster`           | Supported |
| Agent Pools (Node Pools)          | `azurerm_kubernetes_cluster_node_pool` | Supported |
| Kubernetes Resources (in-cluster) | `kubernetes provider resources`        | Supported |

### Azure Container Apps

| Resource                                            | Terraform resource                                                                      | Status    |
| --------------------------------------------------- | --------------------------------------------------------------------------------------- | --------- |
| Container Apps                                      | `azurerm_container_app`                                                                 | Supported |
| Container Apps Environments                         | `azurerm_container_app_environment`                                                     | Supported |
| Container App Certificates                          | `azurerm_container_app_environment_certificate`                                         | Supported |
| Container App Managed Certificates / Custom Domains | `azurerm_container_app_custom_domain / azurerm_container_app_environment_custom_domain` | Supported |
| Container App Jobs                                  | `azurerm_container_app_job`                                                             | Supported |
| Container App Auth Configs                          | `azapi_resource (Microsoft.App/containerApps/authConfigs)`                              | Supported |

### Azure Database for PostgreSQL

| Resource              | Terraform resource                                                  | Status    |
| --------------------- | ------------------------------------------------------------------- | --------- |
| Flexible Servers      | `azurerm_postgresql_flexible_server`                                | Supported |
| PostgreSQL Databases  | `azurerm_postgresql_flexible_server_database`                       | Supported |
| Server Configurations | `azurerm_postgresql_flexible_server_configuration`                  | Supported |
| Entra Administrators  | `azurerm_postgresql_flexible_server_active_directory_administrator` | Supported |
| Firewall Rules        | `azurerm_postgresql_flexible_server_firewall_rule`                  | Supported |

### Azure Monitor

| Resource                 | Terraform resource                | Status    |
| ------------------------ | --------------------------------- | --------- |
| Log Analytics Workspaces | `azurerm_log_analytics_workspace` | Supported |
| {% endtab %}             |                                   |           |
| {% endtabs %}            |                                   |           |


# Audit Log

## Overview

The Audit Log provides a centralized, immutable audit trail of all actions performed within a Firefly tenant. It captures user and API activity across all Firefly domains, including Inventory, Governance, Workflows, Integrations, and more.

The Audit Log is designed for:

* Security and compliance audits
* Operational troubleshooting and debugging
* Change traceability across cloud infrastructure

Every logged event includes contextual metadata such as the actor, action, target, scope, request/response payloads, and execution status.

## What Gets Logged

### Action Scopes

The following domains are covered:

* **Inventory** (`inventory:*`)
* **Workflows** (`workflows:*`)
  * Workspaces
  * Projects
  * Variable sets
  * Workflow runs
* **Governance** (`governance:*`)
* **Integrations** (`integrations:*`)
* **Users, Teams, Roles**
  * `users:*`
  * `teams:*`
  * `roles:*`
* **API Keys** (`api:*`)
* **Notifications** (`notifications:*`)
* **IaC Explorer & Drift Management**
  * `iac-*`
  * `drift-exclude:*`

## Audit Log UI

### Location

**Settings → Audit Log**

### Table View

The Audit Log is displayed as a sortable, paginated table.

### Filtering & Search

The Audit Log supports advanced filtering to quickly locate relevant events.

#### Available Filters

* **Actor** (user or API token)
* **Action** (multi-select)
* **Scope** (multi-select)
* **Status** (success / failure)
* **Time Range** (last X days or custom)

### Exporting Logs

Filtered results can be exported as a CSV file for offline analysis, compliance reviews, or external tooling.

Exports reflect only the currently applied filters.

## RBAC & Visibility

Access to the Audit Log is controlled via RBAC.

* Viewing logs requires the `audit-log:read` permission.
* Visibility is scoped to the user's role and tenant.
* Sensitive fields may be masked based on role permissions (GA).


# SSO Configuration

This guide walks you through configuring Single Sign-On (SSO) with Firefly using your own Identity Provider (IdP).

## Set up the SSO Application

You can configure your SSO integration manually with the assistance of the Firefly Support Team or manage the process using our dedicated Terraform modules. Regardless of the method, the integration involves the following core steps:

* Identity Provider (IdP) Configuration: Create a new SSO application within your IdP (Azure AD or Okta).
* Certificate Procurement: For Okta integrations, please reach out to the Firefly Support Team to receive your required certificate.
* Assignment: Assign your relevant users to the Firefly app within your IdP.
* Metadata Exchange: Extract the SAML metadata from your IdP to finalize the connection.

### Examples

* [Azure AD SSO](https://github.com/gofireflyio/terraform-sso-azure?tab=readme-ov-file#example-usage)
* [Okta SSO](https://github.com/gofireflyio/terraform-sso-okta?tab=readme-ov-file#example-usage)

## Share Your SAML Metadata with Firefly

Please provide us with the SAML metadata URL from your IdP (preferred), or the following details manually:

* Sign in endpoint
* Sign out endpoint
* Signing certificate (PEM format)

## Mapping via IdP Groups (Optional)

Firefly streamlines Role-Based Access Control (RBAC) by synchronizing your internal teams directly with IdP group memberships.

To enable this synchronization, Firefly utilizes a specific naming convention to map IdP groups to RBAC Teams:

* IdP Group Requirement: The group name must use the `firefly-` prefix.
* Mapping Logic: Firefly identifies the target team by stripping the prefix from the IdP group name.
* Example: An IdP group named `firefly-workflows-viewers` will automatically sync with the Firefly team workflows-viewers.

## SCIM Provisioning (Optional)

If you want to enable SCIM provisioning (user/group sync), it must be done via your IdP UI. SCIM configuration details will be provided by Firefly upon request.

## Need Help?

Reach out to our Support Team or email [support@firefly.ai](mailto:help@firefly.ai) for assistance with your SSO configuration.


# OIDC Provider

Firefly can authenticate to your cloud provider using OpenID Connect (OIDC) instead of long-lived static credentials. At execution time Firefly issues a short-lived OIDC token, your cloud provider exchanges it for temporary credentials, and the run proceeds under an identity you control. No static cloud key is ever stored by Firefly.

Setup always has two parts: registering Firefly as an identity provider in your cloud account, then enabling OIDC on the Firefly project or workspace.

## Choose your cloud provider

* [Amazon Web Services (AWS)](/detailed-guides/oidc-provider/aws) — register Firefly as an IAM identity provider and assume an IAM role via web identity.
* [Google Cloud](/detailed-guides/oidc-provider/google-cloud) — register Firefly as an OIDC provider in a workload identity pool and impersonate a service account via Workload Identity Federation.

## Where OIDC is configured in Firefly

For both providers, OIDC can be enabled at either level:

* **Project level** — an inherited attribute. All sub-projects and workspaces within the project pick up the same authentication configuration.
* **Workspace level** — configured per workspace under **Workspace Configuration → Runner Configuration**, and overrides what the project provides.

Each provider guide covers the specific values you need to enter.


# Amazon Web Services (AWS)

This guide will walk you through configuring OpenID Connect (OIDC) authentication between Firefly and AWS. OIDC allows Firefly to securely access your AWS resources without the need for long-lived static credentials.

## Configure Firefly as an Identity Provider

You need to set up Firefly as a valid identity provider for your AWS account. This is done by creating an OpenID Connect identity provider in AWS. Configuration is done via the AWS console:

### Step 1: Access AWS IAM

1. Go to the AWS console and select the IAM service.
2. Click **Identity providers** in the left-hand menu.
3. Click **Add provider** in the top bar.

### Step 2: Configure the Provider

1. Select **OpenID Connect** as the provider type.
2. Enter the following details:
   * **Provider URL:** `https://api.gofirefly.io/v2`
   * **Audience:** `sts.amazonaws.com`
3. Once created, the identity provider will be listed in the "Identity providers" table.

### Step 3: Add Firefly OIDC as the Role Provider

You can click on the provider name to see the details. From here, you will assign an IAM role to this new identity provider:

1. Click **Assign role**, and choose to create a new role.
2. Click **Web identity** and select the new Firefly OIDC provider as the trusted entity.

   ![AWS IAM Create Role - Web Identity Selection](/files/g3h9OK79noc9gYXPZjHU)
3. Select the audience from the dropdown (there should only be one option).

   ![AWS IAM Create Role - Web Identity Configuration](/files/X9wQQtbZ7RRC81by76yq)
4. Add a condition for `:sub` where the value is `account:FIREFLY_ACCOUNT_ID` (replace `FIREFLY_ACCOUNT_ID` with your actual Firefly account ID).

   ![AWS IAM Create Role - Web Identity Condition Configuration](/files/ntRhRxOvMWDROeUkE7e8)
5. The rest of the process is the same as for any other role creation. Select the policies you want to attach to the role, and add tags and a description.

   ![AWS IAM Create Role - Add Permissions](/files/DPnTUUsHyL6OL59dWWln)
6. Once you're done, click **Create role**.

**Example policy:**

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456789:oidc-provider/api.gofirefly.io/v2"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "api.gofirefly.io/v2:sub": "account:123456789",
                    "api.gofirefly.io/v2:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}
```

![AWS IAM Role Created - Permissions Summary](/files/Dw4wK3eYcqu82QejIBNx)

## Required Terraform Configuration

To enable AWS authentication using OIDC / Web Identity, you must define the following variables in your Terraform configuration with no default values:

* `aws_role_arn` – ARN of the IAM role to assume
* `aws_web_identity_token_file` – Path to the OIDC token file used for authentication

### Variable Definitions

Add the following variable definitions to your Terraform code:

```hcl
variable "aws_role_arn" {
  description = "ARN of the IAM role to assume with web identity"
  type        = string
}

variable "aws_web_identity_token_file" {
  description = "Path to the AWS web identity token file"
  type        = string
}
```

### AWS Provider Configuration

Configure your AWS provider to use OIDC authentication:

```hcl
provider "aws" {
  assume_role_with_web_identity {
    role_arn                = var.aws_role_arn
    web_identity_token_file = var.aws_web_identity_token_file
  }
}
```

When Firefly executes your Terraform code, it will automatically provide the values for these variables, allowing secure authentication to AWS without the need for static credentials.

## Configuring OIDC in Firefly

Once you've set up the OIDC provider in AWS, you need to configure Firefly to use it. There are several ways to do this depending on your setup:

### Option 1: Configure OIDC in Projects

> **Note:** OIDC Authentication configured at the project level is an inherited attribute. This means all sub-projects and workspaces within the project will automatically be configured with this authentication method.

#### When Creating a New Project

1. Navigate to the project creation screen
2. Enable **OIDC Authentication**
3. Provide the ARN of the IAM role you created (e.g., `arn:aws:iam::123456789012:role/firefly-oidc-role`)

#### When Editing an Existing Project

1. Navigate to your project settings
2. Enable **OIDC Authentication**
3. Provide the ARN of the IAM role you created (e.g., `arn:aws:iam::123456789012:role/firefly-oidc-role`)

### Option 2: Configure OIDC in Workspaces

1. Navigate to your workspace
2. Go to **Workspace Configuration → Runner Configuration**
3. Enable **OIDC Authentication**
4. Provide the ARN of the IAM role you created (e.g., `arn:aws:iam::123456789012:role/firefly-oidc-role`)


# Google Cloud

Firefly runners can authenticate to Google Cloud using Workload Identity Federation (WIF) instead of a stored service account key. At execution time, Firefly issues a short-lived OIDC token, Google Cloud exchanges it for temporary credentials, and the runner impersonates a service account in your project. No static Google Cloud key is ever stored by Firefly.

Setting this up takes two parts:

* **Part 1** — in your Google Cloud project: create a workload identity pool, add Firefly as an OIDC provider, and grant access to a service account.
* **Part 2** — in Firefly: enable OIDC on the project or workspace and paste in two values from Part 1.

Then check your Terraform code against [Required Terraform configuration](#required-terraform-configuration) below — there's little to add, but one setting will silently bypass federation if it's present.

Plan for about 15 minutes, plus whatever time it takes to get the permissions listed below if you don't already have them.

***

## Before you start

### Enable the required APIs

On a new Google Cloud project, some of these may be off. Enable all four:

| API                                   | Why it's needed                                     |
| ------------------------------------- | --------------------------------------------------- |
| `iam.googleapis.com`                  | Workload identity pools and providers               |
| `sts.googleapis.com`                  | Exchanging the Firefly token for Google credentials |
| `iamcredentials.googleapis.com`       | Service account impersonation                       |
| `cloudresourcemanager.googleapis.com` | Project-level IAM changes                           |

`iamcredentials.googleapis.com` is the one most often missed. Without it, everything appears configured correctly and impersonation fails at run time.

### Check your permissions

You'll need the following roles. If you don't have all of them, note that the project-level grant in Step 5 typically requires a different administrator than the rest of the flow:

| Steps | Role required                                                                                                           |
| ----- | ----------------------------------------------------------------------------------------------------------------------- |
| 1–3   | Workload Identity Pool Admin (`roles/iam.workloadIdentityPoolAdmin`)                                                    |
| 4     | Service Account Admin (`roles/iam.serviceAccountAdmin`), or the ability to edit the target service account's IAM policy |
| 5     | Project IAM Admin (`roles/resourcemanager.projectIamAdmin`)                                                             |

### Check for organization policy restrictions

If your organization enforces `constraints/iam.workloadIdentityPoolProviders`, only allow-listed issuer URIs can be registered. Provider creation in Step 2 will be rejected regardless of your project permissions. If that happens, ask your platform or security team to add the Firefly issuer URL for your environment to the allow-list.

### Collect the values Firefly shows you

Two of the values you'll enter in Google Cloud come from Firefly and are specific to your account.

1. In Firefly, open the workspace you want to configure (**Workspaces → + Workspace**, or open an existing workspace and choose **Edit workspace**).
2. Go to **Workspace Configuration → Runner Configuration**.
3. Check **Enable OIDC authentication**, then select **Google Cloud** under **Cloud provider**.
4. Copy the **attribute condition** and the **principal attribute value** from the panel. Both are shown ready to paste — you don't need to substitute anything into them.

Leave this tab open. You'll come back to it in Part 2.

> **Configuring at the project level instead?** The same panel appears in the project creation and project settings screens, and the two values are identical — they're derived from your Firefly account, not from the workspace. Collect them from wherever you plan to configure OIDC.

***

## Part 1 — Google Cloud setup

Navigate to **IAM & Admin → Workload Identity Federation**. If you have no pools yet, choose **Create pool**; otherwise choose **Add provider** on an existing pool.

### Step 1 — Create an identity pool

* **Name** — for example, `firefly pool`.
* **Description** — optional.
* Leave **Enabled pool** checked.

Then click **Continue**.

> **The pool ID is permanent.** It's derived automatically from the name you enter (`firefly pool` becomes `firefly-pool`) and cannot be changed afterwards. Deleted pool IDs are soft-deleted for 30 days and cannot be reused during that window, so a typo means either living with it or picking a different name. Check the derived ID before saving.

### Step 2 — Add an OIDC provider to the pool

* **Select a provider** — choose **OpenID Connect (OIDC)**. Not AWS, not SAML.
* **Provider name** — for example, `firefly-runner`.
* **Issuer (URL)** — use the value matching your Firefly environment:

| Firefly environment | Issuer URL                     |
| ------------------- | ------------------------------ |
| Production          | `https://api.gofirefly.io/v2`  |
| Production (EU)     | `https://api.eu.firefly.ai/v2` |

> **Include the `/v2` suffix.** This is the exact `iss` claim Firefly puts in the token, not just the domain. Entering the bare domain causes an issuer mismatch that only surfaces when a run fails.

* **JWK file (JSON)** — leave this blank. Firefly's issuer is publicly reachable, so Google Cloud fetches `/.well-known/openid-configuration` and `/.well-known/jwks.json` automatically. A JWK file is only needed for issuers that aren't publicly accessible.
* **Audiences** — select **Allowed audiences**, not **Default audience**, and add exactly one entry:

  ```
  https://runners.firefly.ai
  ```

  This audience is fixed. It's the same for every Firefly environment and region, so unlike the issuer URL it never changes and you only ever configure it once.

Then click **Continue**.

### Step 3 — Configure provider attributes

* **Attribute mapping** — map `google.subject` to `assertion.sub`.
* **Attribute condition (CEL)** — paste the attribute condition you copied from the Firefly panel. It takes this form:

  ```
  assertion.sub == "account:<FIREFLY_ACCOUNT_ID>"
  ```

Click **Save**. You'll land on the pool's details page, which has **Providers** and **Connected service accounts** tabs.

### Step 4 — Allow the Firefly identity to impersonate a service account

Create or choose the service account your runs will act as, for example `firefly-runner@example-project.iam.gserviceaccount.com`.

From the pool's details page, go to **Connected service accounts → Grant Access**. Google Cloud offers two options here:

* **Grant access using service account impersonation** — choose this one.
* **Grant access using federated identities** — do *not* choose this. It issues an Application Default Credentials file intended for direct client-library use. Firefly's runner writes an `external_account` credential config containing a `service_account_impersonation_url`, which requires the impersonation grant instead.

Then:

* **Select service account** — the service account above.
* **Select principals** — set **Attribute name** to `subject`. This is the `google.subject` attribute you mapped in Step 3; the dropdown only offers attributes present in the provider's mapping. For **Attribute value**, paste the **principal attribute value** from the Firefly panel, which takes the form `account:<FIREFLY_ACCOUNT_ID>`.

Click **Save**.

This produces the same IAM binding as running:

```bash
gcloud iam service-accounts add-iam-policy-binding <SA_EMAIL> \
  --role=roles/iam.workloadIdentityUser \
  --member="principal://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/<POOL_ID>/subject/account:<FIREFLY_ACCOUNT_ID>"
```

You can also make the grant from the service account's own **Permissions** tab, using the same `principal://` string as the principal and **Workload Identity User** as the role. All three routes are equivalent — use whichever is most convenient.

#### Why the account ID appears twice

Steps 3 and 4 both reference `account:<FIREFLY_ACCOUNT_ID>`, and it can look like duplication. They're two independent gates, and both are required:

* The **attribute condition** in Step 3 controls *which Firefly accounts the pool will accept a token from at all*. It's enforced at the pool provider.
* The **principal binding** in Step 4 controls *which subject is allowed to impersonate this particular service account*. It's enforced on the service account.

Removing either one either opens the pool to any Firefly account or breaks impersonation. Keep both.

### Step 5 — Grant the service account a role on your project

> **This step is required and is the most common way to misconfigure the integration.** Step 4 and Step 5 modify IAM policies on two different resources, and no wizard prompts you for Step 5. Skip it and Workload Identity Federation will work perfectly while every run still fails with an error like `the user does not have permission to access Project '<PROJECT_ID>' or it may not exist`.
>
> The distinction: **Step 4 determines who may impersonate the service account. Step 5 determines what the service account is actually allowed to do.**

1. Go to **IAM & Admin → IAM** at the project level. This is not the service account's own permissions page.
2. Click **Grant Access**.
3. **Principal** — the service account's email address.
4. **Role** — whatever your infrastructure code actually needs. Start with **Viewer** to confirm access works end to end, then broaden to specific service roles, or to **Editor**, as required.

Firefly doesn't manage or prescribe this role. Scoping it is your IAM decision, based on what your configuration touches.

### Values to carry into Firefly

Two values from Part 1 go into Firefly:

* **Workload identity provider** — the full resource path, shown on the pool's **Providers** tab:

  ```
  //iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/<POOL_ID>/providers/<PROVIDER_ID>
  ```

  The `iam.googleapis.com/` host is part of the value and must be included — a bare `projects/...` path is rejected. Only the leading `//` is optional; Firefly adds it if omitted. Note that this path uses the project *number*, not the project ID.
* **Service account email** — the service account from Step 4.

***

## Part 2 — Firefly configuration

You can enable OIDC at either the project level or the workspace level. Both take the same two values from Part 1.

### Option 1: Configure OIDC in Projects

> **Note:** OIDC Authentication configured at the project level is an inherited attribute. This means all sub-projects and workspaces within the project will automatically be configured with this authentication method.

Whether you're creating a new project or editing an existing one:

1. Navigate to the project creation screen, or to your project settings.
2. Enable **OIDC Authentication**, and select **Google Cloud** under **Cloud provider**.
3. Enter the **Workload identity provider** resource path.
4. Enter the **Service account to impersonate**.
5. Save the project.

### Option 2: Configure OIDC in Workspaces

Back in the workspace panel you left open in *Before you start*:

1. Confirm **Enable OIDC authentication** is checked and **Cloud provider** is set to **Google Cloud**.
2. Enter the **Workload identity provider** resource path.
3. Enter the **Service account to impersonate**.
4. Save the workspace.

Runs now federate to Google Cloud through Workload Identity Federation. This applies to Terraform, OpenTofu, and Terragrunt runs alike.

***

## Required Terraform configuration

Firefly writes an `external_account` credential file on the runner and points Application Default Credentials at it. The `google` provider resolves credentials through ADC, which understands that file natively, so you do **not** need a `credentials` attribute in your provider block. Federation happens without it.

You do still need to tell the provider which project to operate on. Firefly doesn't set this — it's yours to declare, either in the provider block or through the `GOOGLE_PROJECT` environment variable:

```hcl
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 4.0"
    }
  }
}

provider "google" {
  project = "example-project"
  region  = "us-central1"
}
```

The absence of a `credentials` attribute above is deliberate, not an omission.

### Don't override the credentials

> **This is the one way to configure the provider incorrectly, and it fails quietly.** Setting `credentials` in the provider block to your own service account key, or setting `GOOGLE_CREDENTIALS` as a workspace variable, overrides Application Default Credentials and bypasses OIDC entirely. The run will still succeed, using whichever credentials you supplied, so there's no error to alert you. Federation simply isn't being used.
>
> If you're migrating a workspace from a static service account key, removing those values is part of the migration.

### Provider version

Workload Identity Federation support was added in `hashicorp/google` 3.61.0, so that's the minimum. Version 4.0 or later is recommended.

***

## Working across multiple Google Cloud projects

The pool, provider, and impersonation grant from Steps 1–4 live in one project, but the service account can be granted roles in others. If your configuration provisions resources across several projects, Step 5 must be repeated in each of them — grant the same service account an appropriate role on every project it touches, or grant it once at the folder or organization level if the scope justifies that.

Steps 1–4 do not need to be repeated. One pool and provider can serve any number of projects.

***

## Troubleshooting

| Symptom                                                                                  | Likely cause                                                                                                                                                                          |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `the user does not have permission to access Project '<PROJECT_ID>' or it may not exist` | Step 5 was skipped. The service account can be impersonated but has no role on the project.                                                                                           |
| Provider creation is rejected outright                                                   | An organization policy restricts allowed issuer URIs. Ask your platform team to allow-list the Firefly issuer.                                                                        |
| Token exchange fails with an audience error                                              | The audience was entered under **Default audience** instead of **Allowed audiences**, or doesn't exactly match `https://runners.firefly.ai`.                                          |
| Issuer or `iss` claim mismatch                                                           | The `/v2` suffix is missing from the issuer URL, or the URL is for a different Firefly environment.                                                                                   |
| Impersonation fails despite a valid token                                                | `iamcredentials.googleapis.com` isn't enabled, or **Grant access using federated identities** was chosen in Step 4 instead of service account impersonation.                          |
| Provider path is rejected as invalid                                                     | The path contains the project ID instead of the project number, or the `iam.googleapis.com/` host is missing from the front of the value.                                             |
| Runs succeed, but federation clearly isn't being used                                    | `credentials` is set in the provider block to a service account key, or `GOOGLE_CREDENTIALS` is set as a workspace variable. Either overrides ADC and bypasses OIDC without erroring. |
| `google` provider can't use the credential file                                          | The provider version predates 3.61.0, which is where Workload Identity Federation support was added.                                                                                  |
| Terraform errors that no project was specified                                           | `project` isn't set in the provider block and `GOOGLE_PROJECT` isn't defined. Firefly doesn't set this for you.                                                                       |


# Module Registry

> **Note:** Module Registry is available on demand. Contact us to enable this feature for your organization.

## What is Module Registry?

The Module Registry is Firefly's Terraform Private Registry feature that allows you to centrally store, manage, and share Terraform modules across your organization. It provides a secure, private repository where your team can publish reusable infrastructure code modules and consume them directly in your Terraform configurations. This enables better collaboration, standardization, and governance of your infrastructure as code across all your projects.

## Importing a Module

Follow these steps to import a module into your private registry:

### Navigate to the Import Module feature

1. Click **IaC Explorer** in the left sidebar.
2. Click the **Modules** tab.
3. Click the **Import Module** button.

### Configure the module import

The import modal opens with the following fields:

* **Module name:** Enter the name under which the module will be stored in your registry
* **Provider type:** Select the cloud provider this module is associated with (e.g., AWS, Azure, GCP)
* **Version:** Enter the module version (e.g., 1.0.0)
* **VCS integration:** Select your version control system integration
* **Repository:** Select the repository that contains the module
* **Branch:** Select the branch to import from
* **Working directory (optional):** Specify the path within the repository where the module lives; defaults to `/` if left blank. You must choose the base module directory—if the module is nested under another directory layer, it will not work.

### Import the module

Once all values are valid, click the "Import" button.

### Verify the import

After clicking import, the modal will close and the module will appear in the modules table. Note that this action might take a few minutes to complete.

### Access the module call block

Click the + button next to your module in the table to reveal the module call block that you can use in your main.tf file.

## Auto-Discovery from Repository

In addition to [importing modules manually](#importing-a-module), you can configure your repositories to automatically publish modules to the Module Registry. By adding a `.firefly/config.yml` file to your module directory, Firefly detects and publishes the module whenever changes are pushed to your default branch.

Currently supported VCS providers:

* **GitHub**
* **GitLab**

### Set Up Auto-Discovery

1. In your module directory, create a `.firefly` folder with a `config.yml` file inside it.
2. Define the module metadata in `config.yml` (see [Configuration reference](#configuration-reference)).
3. Commit and push the changes to your `main` or `master` branch.
4. The module appears in **IaC Explorer > Modules** within a few minutes.

To publish a new version, update `module_version` in the config file and push again.

### Configuration Reference

**File path:** `.firefly/config.yml`

| Field            | Required | Description                                  | Default |
| ---------------- | -------- | -------------------------------------------- | ------- |
| `module_name`    | Yes      | The module name (for example, `vpc`)         | -       |
| `module_version` | Yes      | Semantic version (for example, `1.0.0`)      | -       |
| `provider`       | No       | Cloud provider (`aws`, `gcp`, `azure`, etc.) | `aws`   |

### Examples

#### Single module (minimal configuration)

Repository structure:

```
my-module/
├── .firefly/
│   └── config.yml
├── main.tf
├── variables.tf
└── outputs.tf
```

`.firefly/config.yml`:

```yaml
module_name: "vpc"
module_version: "1.0.0"
```

This publishes a module named `vpc` at version `1.0.0` with the default provider `aws`.

#### Single module (all fields)

`.firefly/config.yml`:

```yaml
module_name: "vpc"
module_version: "2.1.0"
provider: "gcp"
```

#### Multiple modules in one repository

You can publish multiple modules from a single repository by placing a `.firefly/config.yml` file in each module directory:

```
infra-modules/
├── modules/
│   ├── vpc/
│   │   ├── .firefly/
│   │   │   └── config.yml
│   │   ├── main.tf
│   │   └── variables.tf
│   └── security-group/
│       ├── .firefly/
│       │   └── config.yml
│       ├── main.tf
│       └── variables.tf
└── README.md
```

`modules/vpc/.firefly/config.yml`:

```yaml
module_name: "vpc"
module_version: "1.0.0"
provider: "aws"
```

`modules/security-group/.firefly/config.yml`:

```yaml
module_name: "security-group"
module_version: "1.2.0"
provider: "aws"
```

Each module is discovered and published independently.

## Credentials Setup

To import modules from Firefly's Terraform Private Registry, you'll need to configure authentication for your environment.

### Generate a JWT for the Module Registry

Before configuring your local or CI/CD environment, you need to create a JWT (JSON Web Token) that will be used to authenticate with the Terraform Private Registry.

#### Create an API key pair

1. In the Firefly web console, go to **Settings** and click **Access Management**.
2. Create an API key pair using either:
   * **Users** tab — Create a user API key (each user does this for their own access).
   * **Service Account** tab — Generate a key for the service account (recommended; assign only the permissions required for the registry).

#### Generate the JWT

Use your API key pair (Access Key and Secret Key) to generate a JWT via the Firefly API. For the request body and full details, see the [Authentication](/general-information/api/auth#authentication) section.

When calling the login endpoint, you can optionally set a **`duration`** field to define how long the token is valid. If **`duration`** is omitted, the token does not expire.

You can use the Module Registry from Firefly in three ways: [**integrated CI**](#github-actions-setup) (e.g., GitHub Actions) [**Firefly runners**](#firefly-runners). Choose the setup below that matches your workflow. [**locally**](#local-setup) (on your machine)

### GitHub Actions Setup

When using Firefly's Module Registry in GitHub Actions workflows, you need to provide the authentication token during the Terraform initialization stage. This token allows Terraform to authenticate with the private registry and download the required modules.

Add the following step to your GitHub Actions workflow:

```yaml
- name: Terraform Init
  env:
    TF_TOKEN_api_firefly_ai: ${{ secrets.TF_CLOUD_TOKEN }}
  run: terraform init
```

Make sure to store your Firefly authentication token (generated in the previous step) as a GitHub secret (e.g., `TF_CLOUD_TOKEN`) in your repository settings.

### Firefly Runners

When running Terraform from a Firefly workspace (Firefly runners), provide the registry token as a workspace variable so that `terraform init` can authenticate with the private registry.

1. Open your workspace and go to **Variables Configuration** (in the workspace setup or **Edit Workspace Variables**).
2. Under **Variables**, add a new variable:
   * **Variable name:** `TF_TOKEN_api_firefly_ai`
   * **Variable value:** with the JWT generated in the [Generate a JWT for the Module Registry](#generate-a-jwt-for-the-module-registry) section above.
3. Enable **Sensitive value** and **Environment variable** so the token is available to Terraform and not displayed in logs.

### Local Setup

#### Configure Terraform credentials

In your `~/.terraform.d/credentials.tfrc.json` file, add the following configuration:

```json
{
 "credentials": {
  "api.firefly.ai": {
    "token": "<your-generated-token>"
  }
 }
}
```

Replace `<your-generated-token>` with the JWT generated in the [Generate a JWT for the Module Registry](#generate-a-jwt-for-the-module-registry) section above.

#### Use the module in your Terraform configuration

Once the setup is complete, you can reference modules from the registry using the standard module block syntax:

```hcl
module "example-module" {
  source  = "api.firefly.ai/firefly-authority/example-module/aws"
  version = "8.2.0"
}
```


# Workspace Importer

Firefly Workspace Importer is a lightweight, open-source CLI tool that bulk-imports existing Terraform repositories into Firefly as Workspaces and Projects. Rather than creating workspaces one at a time through the UI, teams onboarding a large number of repositories can point the importer at their VCS integration and let it scan every repository for Terraform directories, then create the matching Firefly Workspaces — and, optionally, a mirrored Project hierarchy — in a single run. Because the tool authenticates only to Firefly's API and reuses the VCS integration you've already configured in Firefly, no GitHub, GitLab, or Bitbucket credentials ever need to be shared with it. It supports a dry-run mode to preview exactly what will be created, an interactive review step before anything is written, and is safe to re-run as new repositories are added. The importer is distributed as a single-file Python script or a distroless Docker image, making it easy to run locally or as part of a CI pipeline during onboarding.

For setup instructions, configuration options, and troubleshooting, see the [Workspace Importer repository](https://github.com/gofireflyio/firefly-workspace-importer) on GitHub.


# Bulk Onboarding

API- and CLI-driven onboarding of cloud accounts into Firefly, without using the Firefly onboarding wizard. Intended for bulk onboarding, CI/CD pipelines, and organizations whose security teams require a reviewable, scriptable integration path.

## When to use this

The Firefly console wizard (**Settings > Integrations > Add New**) is the fastest way to connect a single account, subscription, or project. Use the headless flows below instead when you need to:

* Onboard many accounts at once — an AWS Organization, an Azure management group, a GCP folder tree
* Drive onboarding from a CI/CD pipeline rather than clicking through the console
* Give a security team a template or script they can review, diff, and approve before it runs, rather than a wizard they have to trust
* Re-run onboarding repeatably as new accounts are added to an org, tenant, or project hierarchy

Each guide below covers the provider CLI (`aws`, `az`, `gcloud`) and the Firefly API end to end: creating credentials, granting the minimum required permissions, registering the integration with Firefly, and verifying that data is flowing. Firefly also ships Terraform modules for each provider; those are documented separately under each provider's integration guide.

## Guides

* [**AWS**](/detailed-guides/bulk-onboarding/aws) — Onboard one or many AWS accounts using the `aws` CLI, CloudFormation, and the Firefly API. Includes the AWS Organizations / StackSet path for onboarding at scale.
* [**Azure**](/detailed-guides/bulk-onboarding/azure) — Onboard one or many Azure subscriptions using the `az` CLI and an ARM template that registers the integration with Firefly automatically. Includes management-group deployment and service principal credential rotation.
* [**Google Cloud**](/detailed-guides/bulk-onboarding/google-cloud) — Onboard one or many GCP projects using the `gcloud` CLI and the Firefly API. Includes organization-level folder discovery and the IAM org-policy checks to run before you start.

## Prerequisites common to all three

* Admin access to the Firefly console, to create an API key pair (**Settings > Users > Create Key Pair**)
* `curl` and `jq`
* The relevant provider CLI installed and authenticated (`aws`, `az`, or `gcloud`)
* Sufficient IAM/RBAC permissions in the target cloud to create the read-only role, service principal, or service account that Firefly will use

Provider-specific prerequisites are listed on each guide.


# AWS

**Scope: CLI and API only.** This guide covers the `aws` CLI and the Firefly API for onboarding AWS accounts without the console wizard. Firefly also ships a Terraform module for AWS onboarding, documented separately.

## When to use this

Use this guide to bulk onboard multiple AWS accounts, drive onboarding from a CI/CD pipeline, or give a security team a script to review before it runs. For a single account, the console wizard (**Settings > Integrations > Add New > AWS**) is faster. For an entire AWS Organization, use the StackSet section below rather than looping the single-account flow across every account.

## Prerequisites

* Admin access to the Firefly console (to create an API key pair)
* AWS CLI v2, configured with credentials for each target account
* IAM permissions to create CloudFormation stacks, IAM roles, and IAM policies
* `curl` and `jq`

## The two External ID models

AWS onboarding uses an External ID to secure the cross-account IAM role trust relationship. Which model applies depends on how you deploy:

|                       | Per-account                                                               | Organization-wide                       |
| --------------------- | ------------------------------------------------------------------------- | --------------------------------------- |
| External ID origin    | Generated by Firefly, one ID per registration call                        | One value reused across every account   |
| How you get it        | Returned by the registration call                                         | Provided by your Firefly representative |
| Deployment            | One stack per account, or a StackSet with per-account parameter overrides | A StackSet with OU targeting            |
| Reuse across accounts | No — each registration call issues a new ID                               | Yes, by design                          |

Pick one model and stick to it. Reusing a single External ID while also using the per-account registration call is not supported — either model works on its own, but mixing them does not.

## Flow — single account

1. Create an API key pair in Firefly
2. Authenticate and obtain a bearer token
3. Register the AWS account — this returns the External ID
4. Deploy the CloudFormation stack using that External ID
5. Verify

Steps 3 and 4 repeat per account. Steps 1 and 2 are done once. Registration must happen before the CloudFormation deploy — the registration call is what generates the External ID that the IAM role's trust policy needs.

## Step 1 — Create an API key pair

1. In the Firefly console, go to **Settings > Users**
2. Click **Create Key Pair**
3. Copy both the Access Key and Secret Key immediately — they are shown once
4. Store them in a secrets manager

These keys authenticate to your whole Firefly tenant, not to a single integration. Never commit them to version control.

## Step 2 — Authenticate

```shell
FIREFLY_API="https://prodapi.firefly.ai/api"

TOKEN=$(curl -sS -X POST "${FIREFLY_API}/account/access_keys/login" \
  -H "Content-Type: application/json" \
  -d "{\"accessKey\":\"${FIREFLY_ACCESS_KEY}\",\"secretKey\":\"${FIREFLY_SECRET_KEY}\"}" \
  | jq -r '.access_token // .accessToken')
```

Tokens default to 24-hour validity. For long-running jobs, re-authenticate rather than assuming the token survives.

## Step 3 — Register the account and capture the External ID

```shell
EXTERNAL_ID=$(curl -sS -X POST "${FIREFLY_API}/integrations/aws" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"accountNumber":"123456789012","nickname":"Production AWS"}' \
  | jq -r '.externalId')

echo "External ID: ${EXTERNAL_ID}"
```

| Field           | Type   | Description                                                |
| --------------- | ------ | ---------------------------------------------------------- |
| `accountNumber` | string | 12-digit AWS account ID, no spaces or dashes               |
| `nickname`      | string | Display name in the Firefly console, e.g. `Prod-US-East-1` |

This call queues the account for onboarding; Firefly then attempts to assume the role in the target account using this External ID, so the role must exist with the correct trust policy before validation succeeds.

Settings such as production flagging, event-driven regions, full-scan behavior, and IaC auto-discovery aren't part of this payload — configure those in the console after onboarding.

## Step 4 — Deploy the CloudFormation stack

```shell
aws cloudformation create-stack \
  --stack-name firefly-readonly \
  --template-url https://infralight-templates-public.s3.amazonaws.com/config_template.yml \
  --parameters ParameterKey=ExternalID,ParameterValue="${EXTERNAL_ID}" \
  --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
  --region us-east-1

aws cloudformation wait stack-create-complete \
  --stack-name firefly-readonly --region us-east-1
```

The stack creates a cross-account IAM role with read-only (security audit) permissions, and optionally SNS notifications for event-driven tfstate scanning. The template is public and reviewable at the URL above — share it with security teams that ask.

By default the role is created as `firefly-caa-role`. If your organization requires a custom naming convention for IAM resources, contact your Firefly representative before setting `ResourceNamePrefix` to confirm it stays compatible with role validation.

## AWS Organizations — StackSet via CLI

Above roughly ten accounts, prefer a StackSet to looping the single-account flow. Which permission model you choose follows from which External ID model you're using.

### Option A — service-managed, OU targeting, one shared External ID

The simplest option to operate. Requires trusted access between CloudFormation and AWS Organizations, and must be run from the management or a delegated admin account. New accounts added to a targeted OU are onboarded automatically.

```shell
aws cloudformation create-stack-set \
  --stack-set-name firefly-readonly \
  --template-url https://infralight-templates-public.s3.amazonaws.com/config_template.yml \
  --capabilities CAPABILITY_NAMED_IAM \
  --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
  --parameters ParameterKey=ExternalID,ParameterValue="${SHARED_EXTERNAL_ID}"

aws cloudformation create-stack-instances \
  --stack-set-name firefly-readonly \
  --deployment-targets OrganizationalUnitIds=ou-xxxx-aaaaaaaa,ou-xxxx-bbbbbbbb \
  --regions us-east-1 \
  --operation-preferences MaxConcurrentCount=10,FailureToleranceCount=10,ConcurrencyMode=SOFT_FAILURE_TOLERANCE
```

Contact your Firefly representative to obtain the shared External ID for this deployment model — it isn't the value returned by the per-account registration call in Step 3.

`SOFT_FAILURE_TOLERANCE` matters at scale: without it, a handful of accounts with restrictive SCPs will stall the whole rollout.

### Option B — self-managed, per-account External IDs

Use when each account needs its own External ID from Step 3. StackSet parameter overrides are applied per account, so the same StackSet serves all of them.

Requires `AWSCloudFormationStackSetAdministrationRole` in the admin account and `AWSCloudFormationStackSetExecutionRole` in each target account.

```shell
aws cloudformation create-stack-set \
  --stack-set-name firefly-readonly \
  --template-url https://infralight-templates-public.s3.amazonaws.com/config_template.yml \
  --capabilities CAPABILITY_NAMED_IAM \
  --permission-model SELF_MANAGED \
  --parameters ParameterKey=ExternalID,ParameterValue=placeholder

# per account, using the External ID returned by its own registration call
aws cloudformation create-stack-instances \
  --stack-set-name firefly-readonly \
  --accounts 123456789012 \
  --regions us-east-1 \
  --parameter-overrides ParameterKey=ExternalID,ParameterValue="${EXTERNAL_ID}" \
  --operation-preferences MaxConcurrentCount=5,FailureToleranceCount=5
```

Monitor a rollout with:

```shell
aws cloudformation list-stack-instances --stack-set-name firefly-readonly \
  --query "Summaries[].{Account:Account,Status:Status,Reason:StatusReason}" --output table
```

We recommend validating this approach on two accounts before rolling it out broadly.

## Step 5 — Verify

1. Firefly console > **Settings > Integrations > AWS**
2. Confirm the account appears and shows as connected
3. Open **Inventory** and filter by AWS — initial discovery takes 5–10 minutes

To force a rescan: on the integration menu, **Scan Assets** (cloud resources) or **Scan Stacks** (IaC state).

## Bulk onboarding script

For a set of standalone accounts. For an Organization, prefer the StackSet path above.

```shell
#!/usr/bin/env bash
set -euo pipefail

FIREFLY_API="https://prodapi.firefly.ai/api"
ACCESS_KEY="${FIREFLY_ACCESS_KEY:?set FIREFLY_ACCESS_KEY}"
SECRET_KEY="${FIREFLY_SECRET_KEY:?set FIREFLY_SECRET_KEY}"

# "account_id:nickname:aws_cli_profile"
ACCOUNTS=(
  "123456789012:Production:prod"
  "234567890123:Development:dev"
)

TOKEN=$(curl -sS -X POST "${FIREFLY_API}/account/access_keys/login" \
  -H "Content-Type: application/json" \
  -d "{\"accessKey\":\"${ACCESS_KEY}\",\"secretKey\":\"${SECRET_KEY}\"}" \
  | jq -r '.access_token // .accessToken')

if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
  echo "Authentication failed"; exit 1
fi

for entry in "${ACCOUNTS[@]}"; do
  IFS=':' read -r ACCOUNT_ID NICKNAME PROFILE <<< "$entry"
  echo "=== ${NICKNAME} (${ACCOUNT_ID}) ==="

  EXTERNAL_ID=$(curl -sS -X POST "${FIREFLY_API}/integrations/aws" \
    -H "Authorization: Bearer ${TOKEN}" \
    -H "Content-Type: application/json" \
    -d "{\"accountNumber\":\"${ACCOUNT_ID}\",\"nickname\":\"${NICKNAME}\"}" \
    | jq -r '.externalId')

  if [ -z "$EXTERNAL_ID" ] || [ "$EXTERNAL_ID" = "null" ]; then
    echo "  registration failed, skipping"; continue
  fi

  aws cloudformation create-stack \
    --stack-name firefly-readonly \
    --template-url https://infralight-templates-public.s3.amazonaws.com/config_template.yml \
    --parameters ParameterKey=ExternalID,ParameterValue="${EXTERNAL_ID}" \
    --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
    --region us-east-1 --profile "${PROFILE}"

  aws cloudformation wait stack-create-complete \
    --stack-name firefly-readonly --region us-east-1 --profile "${PROFILE}" \
    && echo "  done" || echo "  stack failed"
done
```

The token is fetched once outside the loop; the External ID is fetched fresh per account. If you extend this past a few dozen accounts, note the API rate limit of 500 requests per rolling minute per source IP.

## Troubleshooting

| Symptom                                             | Likely cause                                                                                                          |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Stack creation fails on IAM resources               | Missing `CAPABILITY_NAMED_IAM`, or the deploying principal cannot create roles                                        |
| Integration stays pending / "unable to assume role" | External ID mismatch between the registration call and the stack parameter, or the role name isn't `firefly-caa-role` |
| Registration returns 401                            | Token expired, or the bearer header is malformed                                                                      |
| No resources in Inventory after 15 min              | Check integration status in the console; confirm the role policy was created and not stripped by an SCP               |
| StackSet rollout stalls partway                     | Restrictive SCPs on some accounts; add `ConcurrencyMode=SOFT_FAILURE_TOLERANCE`                                       |
| StackSet instances fail immediately (self-managed)  | `AWSCloudFormationStackSetExecutionRole` missing in the target account                                                |


# Azure

## Azure

**Scope: CLI and API only.** This guide covers the `az` CLI and the ARM templates for onboarding Azure subscriptions without the console wizard. Firefly also ships a Terraform module for Azure onboarding, documented separately.

**Check which Firefly site your tenant is on before you deploy.** Both templates have a `fireflySite` parameter with allowed values `firefly.ai` and `eu.firefly.ai`, defaulting to `firefly.ai`. If you deploy with the default for an EU-hosted tenant, the embedded script registers against the wrong region and the integration won't appear in your console.

**Set `location` to match your data residency requirements.** It defaults to `westus2` in both templates and controls where the storage account holding your Azure activity logs is created. Leaving the default for an EU-hosted tenant puts activity logs in a US region — set it to an appropriate European region alongside `fireflySite: eu.firefly.ai`.

### When to use this

Use this guide to bulk onboard Azure subscriptions, drive onboarding from a CI/CD pipeline, or give a security team the whole integration as a reviewable template before it runs. For a single subscription, the console wizard (**Settings > Integrations > Add New > Azure**) is faster.

Azure's flow differs from AWS and Google Cloud: the templates contain a deployment script that authenticates to Firefly and registers subscriptions for you. There's no separate manual registration call at the end — your Firefly access key and secret key are template parameters.

### Choosing a flow

There are two templates in the repository, and they are **not** variants of the same deployment — they differ in scope, architecture, and the permissions Firefly ends up with.

|                      | **Flow 1: Subscription-scoped**                                                  | **Flow 2: Management-group-scoped**                                                   |
| -------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Template             | `azurefireflydeploy.json`                                                        | `azurefireflydeploy-managementgroups.json`                                            |
| Deployment command   | `az deployment sub create`                                                       | `az deployment mg create`                                                             |
| Which subscriptions  | Explicit list in `targetSubscriptions`                                           | Every subscription under the management group, discovered recursively at deploy time  |
| Monitoring resources | One resource group **per subscription** (`firefly-monitoring-<subId>`)           | **One shared** resource group in a hub subscription (`firefly-monitoring-mg-<mgId>`)  |
| Role assignments     | Written into each subscription individually                                      | Written **once at the management group scope**, inherited by every subscription below |
| Firefly custom role  | Created and assigned in **every** target subscription                            | Created and assigned in the **hub subscription only** (see the permission gap below)  |
| Best for             | A known, stable set of subscriptions; tenants with no management group hierarchy | Large estates, whole hierarchies, or customers who add subscriptions regularly        |

**Rule of thumb:** one subscription → the console wizard. A handful of known subscriptions → Flow 1. A hierarchy, or more subscriptions than you want to list by hand → Flow 2.

The two flows aren't mutually exclusive. A common pattern is Flow 2 across the hierarchy for broad inventory, plus Flow 1 targeted at the few subscriptions where full IaC and secret-adjacent discovery is required — see the permission gap under Flow 2.

### Prerequisites

Common to both flows:

* Admin access to the Firefly console (to create the API key pair)
* Azure CLI, authenticated
* Application Administrator or Global Administrator in Entra ID, to create the service principal
* The Entra ID **primary domain** of your tenant — `directoryDomain` is a **required** parameter in both templates with no default
* `git`, and `jq` if you script the parameter file
* These providers registered in the subscription hosting the deployment: `Microsoft.Storage`, `Microsoft.EventGrid`, and `Microsoft.ContainerInstance` (the deployment scripts run as container instances)

Flow 1 additionally needs:

* Owner or Contributor on every subscription in `targetSubscriptions`
* User Access Administrator or Owner on those subscriptions, to create role assignments

Flow 2 additionally needs:

* **Owner or User Access Administrator at the management group scope** — role assignments are written at the management group, not per subscription
* Contributor on the hub subscription named in `subscriptionIdForDeployment`
* All subscriptions in the same Entra ID tenant. If you have more than one tenant, you need a separate service principal, hub subscription, and deployment for each
* Elevated access, if you're targeting the Tenant Root Group — see "Which management group to target" below

### Phase A — Firefly key pair

Create the key pair under **Settings > Users > Create Key Pair**. Copy both values; they are shown once. These go straight into the deployment parameters, so treat the parameter file as a secret from the moment you create it.

### Phase B — Clone and authenticate

```shell
git clone https://github.com/gofireflyio/arm-firefly-azure-onboarding.git
cd arm-firefly-azure-onboarding
```

| File                                       | Purpose                                   |
| ------------------------------------------ | ----------------------------------------- |
| `azurefireflydeploy.json`                  | Flow 1, subscription-scoped template      |
| `azurefireflydeploy-managementgroups.json` | Flow 2, management-group-scoped template  |
| `CreateUIDefinition.json`                  | Azure Portal guided-deployment UI, Flow 1 |
| `CreateUIDefinition-managementgroups.json` | Azure Portal guided-deployment UI, Flow 2 |
| `README.md`                                | Repository documentation                  |

```shell
az login
# multi-tenant: az login --tenant YOUR_TENANT_ID
az account list --output table
```

### Phase C — Service principal

Create it once. What differs between flows is the scope you grant it.

**Flow 1 — scope to the subscription:**

```shell
az ad sp create-for-rbac \
  --name "Firefly-Integration" \
  --role Reader \
  --scopes /subscriptions/YOUR_SUBSCRIPTION_ID
```

**Flow 2 — scope to the management group:**

```shell
az ad sp create-for-rbac \
  --name "Firefly-Integration-MG" \
  --role Reader \
  --scopes "/providers/Microsoft.Management/managementGroups/YOUR_MG_ID"
```

The management-group-scoped grant covers every subscription in the hierarchy through inheritance, so there's no per-subscription role assignment loop in Flow 2. The template writes its own management-group-scope assignments during deployment, so this initial grant is belt-and-braces — you can omit `--role` and `--scopes` entirely and let the template do all of it.

The output contains `appId`, `password`, and `tenant`. The password cannot be retrieved again — capture it now. Then fetch the object ID, a different value from `appId`, which the templates need for role assignments:

```shell
az ad sp show --id "YOUR_APP_ID" --query id --output tsv
# fallback:
az ad sp list --display-name "Firefly-Integration" --query "[0].id" --output tsv
```

| CLI output                  | Template parameter             |
| --------------------------- | ------------------------------ |
| `appId`                     | `servicePrincipalClientId`     |
| `password`                  | `servicePrincipalClientSecret` |
| `id` (from `az ad sp show`) | `servicePrincipalObjectId`     |

**The secret has an expiry date, and the integration fails silently when it lapses.** `az ad sp create-for-rbac` issues a client secret with a finite lifetime — commonly one year, depending on tenant policy. Nothing warns you beforehand; asset collection simply stops and Inventory quietly goes stale. Record the expiry at onboarding and set a reminder. See Credential rotation below.

***

## Flow 1: Subscription-scoped deployment

Use for a known list of subscriptions. The template loops over `targetSubscriptions` and provisions a full, independent monitoring stack into each one.

#### 1. Set subscription context

```shell
az account set --subscription "YOUR_SUBSCRIPTION_ID"
az account show --output table
```

#### 2. Build the parameters file

```json
{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location":                     { "value": "westus2" },
    "fireflySite":                  { "value": "firefly.ai" },
    "directoryDomain":              { "value": "customer.onmicrosoft.com" },
    "servicePrincipalObjectId":     { "value": "YOUR_SP_OBJECT_ID" },
    "servicePrincipalClientId":     { "value": "YOUR_SP_CLIENT_ID" },
    "servicePrincipalClientSecret": { "value": "YOUR_SP_CLIENT_SECRET" },
    "fireflyAccessKey":             { "value": "YOUR_FIREFLY_ACCESS_KEY" },
    "fireflySecretKey":             { "value": "YOUR_FIREFLY_SECRET_KEY" },
    "targetSubscriptions":          { "value": ["YOUR_SUBSCRIPTION_ID"] },
    "isMultiSubscription":          { "value": false },
    "eventDrivenEnabled":           { "value": true },
    "isProd":                       { "value": false },
    "enforceStorageNetworkRules":   { "value": false },
    "tags": {
      "value": [
        { "tagName": "Environment", "tagValue": "Production" },
        { "tagName": "ManagedBy",   "tagValue": "Firefly" }
      ]
    }
  }
}
```

| Parameter                      | Type         | Template default         | Notes                                                                                                                                                                               |
| ------------------------------ | ------------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `location`                     | string       | `westus2`                | Region for the Firefly monitoring resources. Set it for data residency                                                                                                              |
| `fireflySite`                  | string       | `firefly.ai`             | **Set to `eu.firefly.ai` for EU tenants.** Drives both the API base and the event webhook host                                                                                      |
| `directoryDomain`              | string       | **required, no default** | Entra ID domain. The deployment fails validation without it                                                                                                                         |
| `servicePrincipalObjectId`     | string       | required                 | Object ID, not app ID                                                                                                                                                               |
| `servicePrincipalClientId`     | string       | required                 | `appId`                                                                                                                                                                             |
| `servicePrincipalClientSecret` | securestring | required                 | `password`                                                                                                                                                                          |
| `fireflyAccessKey`             | securestring | required                 | Used by the embedded script to authenticate                                                                                                                                         |
| `fireflySecretKey`             | securestring | required                 | As above                                                                                                                                                                            |
| `targetSubscriptions`          | array        | current subscription     | Every subscription to onboard                                                                                                                                                       |
| `isMultiSubscription`          | bool         | `true`                   | Template defaults to true; set `false` for a single subscription                                                                                                                    |
| `eventDrivenEnabled`           | bool         | `true`                   | Event Grid real-time monitoring                                                                                                                                                     |
| `isProd`                       | bool         | `false`                  | Marks the integration as production                                                                                                                                                 |
| `enforceStorageNetworkRules`   | bool         | `false`                  | Applies network rules to the log storage account, restricted to Firefly egress IPs                                                                                                  |
| `fireflyWebhookUrl`            | string       | empty                    | Overrides the default `https://azure-events.{fireflySite}`. Leave empty unless instructed otherwise                                                                                 |
| `fireflyEips`                  | array        | Firefly egress IPs       | **Fallback only.** A deployment script fetches the live list from `https://api.{fireflySite}/v2/infrastructure/public-nat-ips` and only falls back to this array if that call fails |
| `tags`                         | array        | `[]`                     | Applied to created resources                                                                                                                                                        |

The parameter file holds the service principal secret and both Firefly keys in plaintext. Add it to `.gitignore` before you populate it, and delete it from your workstation once the deployment succeeds.

#### 3. Validate and preview

```shell
az deployment sub validate \
  --location westus2 \
  --template-file azurefireflydeploy.json \
  --parameters @parameters.json

az deployment sub what-if \
  --location westus2 \
  --template-file azurefireflydeploy.json \
  --parameters @parameters.json
```

`what-if` is worth running in front of your security team — it shows exactly what the template will create before anything is committed.

#### 4. Deploy

```shell
az deployment sub create \
  --name firefly-deployment-$(date +%s) \
  --location westus2 \
  --template-file azurefireflydeploy.json \
  --parameters @parameters.json
```

Expect 5–15 minutes. Per subscription in the array, the template creates a resource group (`firefly-monitoring-<subscriptionId>`), a storage account for activity logs, an Event Grid system topic and subscription, custom role definitions, role assignments, and diagnostic settings — then runs the deployment script that registers everything with Firefly.

**Locked-down subscriptions:** the registration step runs as an ARM `deploymentScripts` resource, which provisions its own storage account and container instance behind the scenes. Azure Policy that denies public storage endpoints or mandates private endpoints will block it, and the failure surfaces as "deployment succeeded, script failed" — which looks like a Firefly problem but is a policy problem. Check for such policies before deploying into a regulated subscription.

#### 5. Adding more subscriptions

Grant the service principal Reader on each additional subscription, then list them all in `targetSubscriptions`:

```shell
for SUB in SUBSCRIPTION_ID_2 SUBSCRIPTION_ID_3; do
  az role assignment create \
    --assignee YOUR_SP_APP_ID \
    --role Reader \
    --scope "/subscriptions/${SUB}"
done
```

Set `isMultiSubscription` to `true` and redeploy. All subscriptions must sit in the same Entra ID tenant.

If this loop is getting long, you want Flow 2.

***

## Flow 2: Management-group-scoped deployment

Use for bulk onboarding across a hierarchy. You name one management group; the template discovers every subscription beneath it recursively, including subscriptions in nested child management groups, and registers each one as its own Firefly integration.

#### How this flow is architecturally different

This is not simply "Flow 1 with a wider net" — read this before deploying.

* **Role assignments are written once, at the management group scope,** and inherit downward. Six built-in roles: Reader, Billing Reader, App Configuration Data Reader, Security Reader, **Monitoring Reader**, and **Management Group Reader**. The last two don't appear in Flow 1 at all.
* **Monitoring infrastructure is centralized, not per-subscription.** One resource group (`firefly-monitoring-mg-<managementGroupId>`), one storage account, and one Event Grid system topic are created in the hub subscription you nominate via `subscriptionIdForDeployment`. Every subscription in the hierarchy gets a diagnostic setting pointing at that single shared storage account. Flow 1, by contrast, builds a complete stack in each subscription.
* **A diagnostic setting is also written at the management group scope itself**, capturing management-group-level activity, in addition to the per-subscription ones.
* **Each subscription still becomes its own Firefly integration.** The management group is the deployment scope, not the unit of integration. A 200-subscription hierarchy produces 200 integrations in the console, named after each subscription's display name.

#### Permission gap versus Flow 1 (read this)

The Firefly custom role and the conditional Storage Blob Data Reader assignment are created with `assignableScopes` limited to the hub subscription, and are **only assigned there** — they are not propagated across the management group.

In practice, every subscription other than the hub gets read-level inventory and billing visibility from Firefly, but **not** the elevated permissions the custom role grants (storage account keys, database connection strings, AKS cluster credentials, web app configuration, Redis keys, search service keys, and Log Analytics workspace keys), and **not** the conditional blob access used to read Terraform state objects.

**Consequence:** Terraform state discovery and IaC mapping won't work in non-hub subscriptions under a pure Flow 2 deployment. If you need that, either run Flow 1 additionally against the subscriptions holding your state backends, or reach out to Firefly about it. Don't assume the management-group deployment covers it — set this expectation during a POC rather than after.

#### Which management group to target

Don't reflexively pick the Tenant Root Group. Two things make a lower, more specific management group the better choice in most estates.

`isProd` and `tags` apply to the whole deployment — they're single values, written identically to every subscription the run discovers. A real hierarchy contains production and non-production subscriptions side by side, so one root-level run mislabels a large part of the estate in Firefly and makes your environment filters useless.

The pattern that works is one run per branch: a deployment against the production management group with `isProd: true` and production tags, then a second against the non-production management group with its own values. Both runs can share the same service principal and hub subscription — only the parameter file changes. Split further if tagging conventions differ by business unit.

**The Tenant Root Group needs elevated access.** Deploying at root requires a Global Administrator to enable "Access management for Azure resources" in Entra ID, which grants them User Access Administrator at root, and then to assign the deploying identity there. Without it, the role assignment step fails with an authorization error that never mentions the root group:

```shell
# Global Administrator, once, and reverse it afterwards
az rest --method post \
  --url "https://management.azure.com/providers/Microsoft.Authorization/elevateAccess?api-version=2016-07-01"
```

Have the Global Administrator reverse the elevation once the deployment completes. If a lower management group covers the subscriptions you care about, targeting it avoids this step entirely.

#### 1. Inspect the hierarchy first

Always do this before deploying — it tells you the management group ID to use and exactly how many subscriptions you're about to onboard.

```shell
# list management groups
az account management-group list --output table

# full recursive tree, for visual inspection
az account management-group show \
  --name "YOUR_MG_ID" --expand --recurse --output json
```

Note the ID (`name` field), not the display name — `managementGroupId` expects the ID.

To count the subscriptions you're about to onboard, use the descendants API. A JMESPath query against `children` returns only the direct children of the management group, so on any hierarchy deeper than one level it undercounts — you'd later conclude the deployment failed when it didn't:

```shell
az rest --method get \
  --url "https://management.azure.com/providers/Microsoft.Management/managementGroups/YOUR_MG_ID/descendants?api-version=2021-04-01" \
  --query "value[?type=='Microsoft.Management/managementGroups/subscriptions'].{id:name, name:properties.displayName}" \
  --output table

# just the count
az rest --method get \
  --url "https://management.azure.com/providers/Microsoft.Management/managementGroups/YOUR_MG_ID/descendants?api-version=2021-04-01" \
  --query "length(value[?type=='Microsoft.Management/managementGroups/subscriptions'])"
```

Record that number — it's what you check the deployment against afterward. If the management group contains subscriptions you didn't intend to onboard, move them or pick a lower management group in the tree. There's no exclusion parameter.

#### 2. Choose the hub subscription

`subscriptionIdForDeployment` is required and has no default. It nominates the subscription that will host the shared monitoring resources and run the deployment scripts. Choose one that is:

* long-lived and not scheduled for decommissioning
* not subject to Azure Policy that blocks public storage endpoints or container instances
* the subscription holding your Terraform state backends, if you have a central one — that maximizes what the custom role can reach given the permission gap above

#### 3. Build the parameters file

Note the different `$schema` — a subscription-scoped parameters file won't validate here.

```json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "managementGroupId":            { "value": "YOUR_MG_ID" },
    "subscriptionIdForDeployment":  { "value": "YOUR_HUB_SUBSCRIPTION_ID" },
    "location":                     { "value": "westus2" },
    "fireflySite":                  { "value": "firefly.ai" },
    "directoryDomain":              { "value": "customer.onmicrosoft.com" },
    "servicePrincipalObjectId":     { "value": "YOUR_SP_OBJECT_ID" },
    "servicePrincipalClientId":     { "value": "YOUR_SP_CLIENT_ID" },
    "servicePrincipalClientSecret": { "value": "YOUR_SP_CLIENT_SECRET" },
    "fireflyAccessKey":             { "value": "YOUR_FIREFLY_ACCESS_KEY" },
    "fireflySecretKey":             { "value": "YOUR_FIREFLY_SECRET_KEY" },
    "eventDrivenEnabled":           { "value": true },
    "isProd":                       { "value": true },
    "enforceStorageNetworkRules":   { "value": false },
    "tags": {
      "value": [
        { "tagName": "ManagedBy", "tagValue": "Firefly" }
      ]
    }
  }
}
```

Parameters that differ from Flow 1:

| Parameter                     | Type   | Default                  | Notes                                                                                                             |
| ----------------------------- | ------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| `managementGroupId`           | string | current management group | The management group ID, not display name. Defaults to the group you deploy into, but set it explicitly           |
| `subscriptionIdForDeployment` | string | **required, no default** | Hub subscription hosting the shared resource group, storage account, Event Grid topic, and the deployment scripts |
| `targetSubscriptions`         | n/a    | n/a                      | **Does not exist in this template.** Subscriptions are discovered, not listed                                     |
| `isMultiSubscription`         | n/a    | n/a                      | **Does not exist in this template.** Multi-subscription is implicit                                               |

All other parameters (`fireflySite`, `directoryDomain`, the service principal trio, the Firefly key pair, `eventDrivenEnabled`, `isProd`, `enforceStorageNetworkRules`, `fireflyWebhookUrl`, `fireflyEips`, `tags`) behave exactly as in the Flow 1 table above.

#### 4. Validate and preview

```shell
az deployment mg validate \
  --management-group-id "YOUR_MG_ID" \
  --location westus2 \
  --template-file azurefireflydeploy-managementgroups.json \
  --parameters @parameters-mg.json

az deployment mg what-if \
  --management-group-id "YOUR_MG_ID" \
  --location westus2 \
  --template-file azurefireflydeploy-managementgroups.json \
  --parameters @parameters-mg.json
```

`--location` is mandatory for management-group-scoped deployments even though the management group itself isn't regional — it sets where deployment metadata is stored.

`what-if` will show the management-group-scope role assignments and the hub-subscription resources, but **not** the per-subscription diagnostic settings or the Firefly integrations — those are created by deployment scripts at runtime and are invisible to `what-if`. If a security team asks why the preview looks smaller than expected, that's why.

#### 5. Deploy

```shell
az deployment mg create \
  --name firefly-mg-$(date +%s) \
  --management-group-id "YOUR_MG_ID" \
  --location westus2 \
  --template-file azurefireflydeploy-managementgroups.json \
  --parameters @parameters-mg.json
```

Expect longer than Flow 1. Both scripts process subscriptions serially, with a deliberate pause between each, so allow roughly 15–30 minutes for a large hierarchy.

**There's a ceiling.** The deployment scripts have a 30-minute timeout and no resume, so a hierarchy large enough to exceed it fails partway with no way to continue from where it stopped. Somewhere in the low hundreds of subscriptions is where this starts to matter. At that scale, split the work by child management group and run one deployment per branch — which is also what you want for `isProd` accuracy.

#### 6. What the deployment scripts actually do

Three scripts run, all as AzurePowerShell deployment scripts in the hub subscription.

1. **IP fetch.** Calls `https://api.{fireflySite}/v2/infrastructure/public-nat-ips` for the live Firefly egress IP list, falling back to the `fireflyEips` array if unreachable.
2. **Diagnostics.** Authenticates as the service principal, walks the management group hierarchy recursively, and writes a diagnostic setting named `firefly-mg-diagnostics-<subId>` into each subscription, covering Administrative, Security, ServiceHealth, Alert, Recommendation, Policy, Autoscale, and ResourceHealth logs — all targeting the shared hub storage account.
3. **Integration.** Authenticates to Firefly, waits 30 seconds for role assignments to propagate, walks the hierarchy again, and registers each subscription:

```
POST /api/account/access_keys/login                 → exchanges the key pair for a token
POST /api/integrations/azure?onConflictUpdate=true   → registers each subscription
```

`onConflictUpdate=true` means re-running the deployment updates existing integrations rather than failing, so redeploys are safe.

Behavior worth knowing:

* **Disabled subscriptions are skipped** silently. If the count in Firefly is lower than the count in the management group, check subscription state first.
* **Integration names are the subscription display names, sanitized.** Anything outside `A-Z a-z 0-9 space _ : . @ / + , -` is replaced with a hyphen, runs of hyphens are collapsed, and leading non-alphanumerics are stripped. A subscription whose name is entirely special characters falls back to its subscription ID. Expect cosmetic name differences between Azure and Firefly for decorated naming conventions.
* **A per-subscription failure does not fail the deployment.** The script logs a warning, adds the subscription to a failed list, and continues — it only errors out if every subscription failed. Always read the script output (see Verify).
* **The Firefly API can return HTTP 200 with a validation error in the body.** The script detects this and counts it as a failure, but the deployment still reports success overall.

#### 7. The auto-discovery caveat: correct expectation setting

The repository README describes "automatic discovery of new subscriptions." That's **partially** true, and it's the most common source of a wrong customer expectation. Be precise:

| When a subscription is added to the hierarchy later | What happens                                                                                                                |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| RBAC role assignments                               | **Inherited automatically.** Management-group-scope assignments apply to the new subscription immediately, no action needed |
| Diagnostic settings                                 | **Not created.** The diagnostics script only ran at deploy time                                                             |
| Firefly integration / registration                  | **Not created.** The new subscription won't appear in the Firefly console                                                   |

This is **not** the equivalent of AWS StackSet auto-deployment. To pick up subscriptions added after the initial deployment, **re-run the same** `az deployment mg create` command. It's idempotent: `onConflictUpdate=true` updates existing integrations rather than duplicating them, and existing diagnostic settings are updated in place.

Set up either a scheduled redeploy (a pipeline running the same command monthly, or on subscription-vending events) or a documented runbook step in your subscription provisioning process. Raise this during a POC rather than discovering it three months later with a stale inventory.

#### 8. Management-group-specific failure modes

**Missing Management Group Reader is the dangerous one.** If the service principal can't enumerate the hierarchy, the script doesn't fail — it catches the error, logs a warning, and **falls back to onboarding only the hub subscription.** The deployment reports success. One integration appears instead of two hundred, and unless you read the script log the cause is invisible. If the subscription count is wrong, check this first.

**Azure Policy blocking deployment scripts.** The registration and diagnostics steps run as ARM `deploymentScripts`, which provision their own storage account and container instance in the hub subscription. Policy that denies public storage endpoints, mandates private endpoints, or restricts container instances will block them, and the failure surfaces as "deployment succeeded, script failed" — which reads as a Firefly problem when it's a policy problem. Management group hierarchies almost always carry inherited policy, so check the hub subscription's effective policy before deploying:

```shell
az policy assignment list --scope "/subscriptions/YOUR_HUB_SUBSCRIPTION_ID" --output table
```

**Provider registration is per-subscription.** `Microsoft.Storage`, `Microsoft.EventGrid`, and `Microsoft.ContainerInstance` must be registered in the hub subscription. Diagnostic settings additionally require `Microsoft.Insights` in each target subscription — that's usually already registered, but a fresh subscription in the hierarchy may not have it.

***

### What this costs

The integration itself is free. What you pay for is the Azure infrastructure the template creates:

* **Storage account**, holding activity logs. Flow 1 creates one per subscription; Flow 2 creates one shared account. Usually the largest line item, and it scales with activity volume — a busy production subscription costs more than a dormant one.
* **Event Grid system topic and subscription**, only when `eventDrivenEnabled` is true. Priced per operation with the first 100,000 operations each month free, so this is typically negligible.
* **Deployment scripts**, which run a container instance and a temporary storage account during deployment only. Cents, once.
* **Diagnostic settings** carry no charge themselves; the cost is the storage they write to.

For most customers the whole thing lands in the low tens of dollars per month. Activity log volume is the variable, and a lifecycle management policy on the storage account is the lever if it grows. Flow 2 is generally cheaper than Flow 1 across the same number of subscriptions, since there's one storage account rather than many.

### Verify

**Flow 2 first step: read the deployment script output.** This is where partial failures live, and neither Azure nor Firefly surfaces them elsewhere.

```shell
az deployment mg show \
  --management-group-id "YOUR_MG_ID" \
  --name DEPLOYMENT_NAME \
  --query "properties.outputs"

# the integration script's own log, in the hub subscription
az deployment-scripts list \
  --query "[?contains(name,'firefly-integration')].{name:name, state:provisioningState}" -o table
az deployment-scripts show-log --resource-group firefly-monitoring-mg-YOUR_MG_ID --name SCRIPT_NAME
```

The script prints an `=== INTEGRATION SUMMARY ===` block with total subscriptions found, successful integrations, and a named list of failures with reasons. Compare the total against your Step 1 hierarchy count.

**If some subscriptions failed**, the fix depends on the reason given. Transient API errors and rate limiting usually clear on a straight re-run of the same deployment, which is safe and idempotent. Authorization errors on specific subscriptions normally mean the management-group role assignments hadn't finished propagating when that subscription was processed, and a re-run resolves those too. A subscription that fails repeatedly is usually blocked by something local to it, such as policy or a disabled state, and is faster to onboard with a targeted Flow 1 run than to keep retrying the whole hierarchy.

Azure-side checks:

```shell
# Flow 1: one resource group per subscription
az group list --query "[?contains(name,'firefly-monitoring')].{Name:name, Location:location}" -o table

# Flow 2: one shared resource group in the hub subscription
az group show --name firefly-monitoring-mg-YOUR_MG_ID -o table
az resource list --resource-group firefly-monitoring-mg-YOUR_MG_ID -o table

# Flow 2: management-group-scope role assignments
az role assignment list \
  --assignee YOUR_SP_OBJECT_ID \
  --scope "/providers/Microsoft.Management/managementGroups/YOUR_MG_ID" \
  --output table

# Flow 2: spot-check diagnostic settings in a non-hub subscription
az monitor diagnostic-settings subscription list \
  --subscription ANOTHER_SUB_ID \
  --query "[?contains(name,'firefly')]"
```

Expected role assignments:

| Role                                                    | Flow 1 (per subscription) | Flow 2 (at management group, inherited) |
| ------------------------------------------------------- | ------------------------- | --------------------------------------- |
| Reader                                                  | yes                       | yes                                     |
| Billing Reader                                          | yes                       | yes                                     |
| Security Reader                                         | yes                       | yes                                     |
| App Configuration Data Reader                           | yes                       | yes                                     |
| Monitoring Reader                                       | no                        | yes                                     |
| Management Group Reader                                 | no                        | yes                                     |
| Storage Blob Data Reader (conditional, Terraform state) | yes                       | hub subscription only                   |
| Firefly custom role                                     | yes                       | hub subscription only                   |

Then in the console: **Settings > Integrations > Azure**, confirm the expected number of subscriptions is listed and connected, and check **Inventory** filtered to Azure after 10–15 minutes. If event-driven is on, change a test resource and confirm it surfaces within a couple of minutes.

For a large hierarchy, counting integrations in the console by eye is unreliable. Pull the count from the API instead, using the same key pair the deployment used:

```shell
TOKEN=$(curl -s -X POST "https://prodapi.firefly.ai/api/account/access_keys/login" \
  -H "Content-Type: application/json" \
  -d '{"accessKey":"YOUR_ACCESS_KEY","secretKey":"YOUR_SECRET_KEY"}' | jq -r .access_token)

curl -s "https://prodapi.firefly.ai/api/integrations/azure" \
  -H "Authorization: Bearer $TOKEN" | jq 'length'
```

Substitute `eu.firefly.ai` for EU tenants. That number should match the subscription count from Step 1, less any disabled subscriptions.

### Credential rotation

Applies to both flows. Check when the secret expires, at onboarding and periodically thereafter:

```shell
az ad app credential list --id YOUR_SP_CLIENT_ID \
  --query "[].{keyId:keyId, start:startDateTime, end:endDateTime}" --output table
```

To rotate before expiry, add a new secret, redeploy the template with it, then remove the old one:

```shell
# 1. new secret
az ad app credential reset --id YOUR_SP_CLIENT_ID --append --years 1

# 2. update servicePrincipalClientSecret in the parameter file, then redeploy
#    Flow 1:
az deployment sub create --name firefly-rotate-$(date +%s) --location westus2 \
  --template-file azurefireflydeploy.json --parameters @parameters.json
#    Flow 2:
az deployment mg create --name firefly-rotate-$(date +%s) \
  --management-group-id "YOUR_MG_ID" --location westus2 \
  --template-file azurefireflydeploy-managementgroups.json --parameters @parameters-mg.json

# 3. remove the superseded secret
az ad app credential delete --id YOUR_SP_CLIENT_ID --key-id OLD_KEY_ID
```

The redeploy is safe — `onConflictUpdate=true` updates existing integrations in place rather than creating duplicates. Use `--append` on the reset so the old secret keeps working until the new one is live; otherwise collection stops between steps 1 and 2.

**Flow 2 note:** rotation redeploys the whole hierarchy, so it doubles as a resync — any subscriptions added since the last deployment get picked up at the same time.

### Troubleshooting

| Symptom                                                                 | Likely cause                                                                                                                                           |
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Deployment succeeds, nothing in Firefly                                 | `fireflySite` wrong for the tenant's region, or an incorrect Firefly key pair. Check the deployment script output                                      |
| **Flow 2: only the hub subscription onboarded**                         | Service principal lacks Management Group Reader. The script fell back silently. The most common management-group failure                               |
| **Flow 2: fewer integrations than subscriptions**                       | Disabled subscriptions are skipped, or there were per-subscription failures. Read the `INTEGRATION SUMMARY` block                                      |
| **Flow 2: integration names differ from Azure**                         | Name sanitization stripped unsupported characters. Cosmetic                                                                                            |
| **Flow 2: new subscription not appearing**                              | Expected — registration isn't automatic. Re-run the deployment                                                                                         |
| Template validation fails on the management-group template              | Wrong `$schema` in the parameter file, or `subscriptionIdForDeployment` / `directoryDomain` missing. Both are required with no default                 |
| `--location` missing error                                              | Mandatory on `az deployment mg create` even though management groups aren't regional                                                                   |
| Worked for months, then stopped                                         | Service principal secret expired — see Credential rotation                                                                                             |
| "Deployment succeeded, script failed"                                   | Azure Policy blocking the `deploymentScripts` storage account or container instance in the hub subscription                                            |
| Service principal creation fails                                        | Missing Application Administrator, tenant app registration limit, or a name collision                                                                  |
| Insufficient permissions on deploy                                      | Flow 2 needs Owner or User Access Administrator **at the management group**, not just on subscriptions                                                 |
| Authorization error deploying at the Tenant Root Group                  | Elevated access not granted — see "Which management group to target"                                                                                   |
| Activity logs stop arriving after enabling `enforceStorageNetworkRules` | The storage firewall is denying Azure Monitor. Confirm the storage account permits trusted Azure services and that the Firefly IP allowlist is current |
| Role assignment errors                                                  | `servicePrincipalObjectId` populated with the app ID instead of the object ID                                                                          |
| Terraform state not discovered outside the hub subscription (Flow 2)    | Expected — see the permission gap section                                                                                                              |
| Event-driven not firing                                                 | Event Grid system topic or subscription missing, or the webhook endpoint doesn't match the tenant's site                                               |

```shell
# Flow 1
az deployment sub show --name DEPLOYMENT_NAME --query "properties.error"
az deployment operation sub list --name DEPLOYMENT_NAME \
  --query "[?properties.provisioningState=='Failed']"

# Flow 2
az deployment mg show --management-group-id "YOUR_MG_ID" --name DEPLOYMENT_NAME --query "properties.error"
az deployment operation mg list --management-group-id "YOUR_MG_ID" --name DEPLOYMENT_NAME \
  --query "[?properties.provisioningState=='Failed']"
```

### Removal

Remove the integrations in the Firefly console first, then clean up Azure.

**Flow 1:**

```shell
az group delete --name firefly-monitoring-YOUR_SUBSCRIPTION_ID --yes --no-wait
az role assignment delete --assignee YOUR_SP_OBJECT_ID --scope /subscriptions/YOUR_SUBSCRIPTION_ID
```

**Flow 2:**

```shell
# shared monitoring resource group in the hub subscription
az group delete --name firefly-monitoring-mg-YOUR_MG_ID --yes --no-wait

# management-group-scope role assignments
az role assignment delete --assignee YOUR_SP_OBJECT_ID \
  --scope "/providers/Microsoft.Management/managementGroups/YOUR_MG_ID"

# management-group-level diagnostic setting
az monitor diagnostic-settings delete \
  --resource "/providers/Microsoft.Management/managementGroups/YOUR_MG_ID" \
  --name DIAGNOSTIC_NAME

# per-subscription diagnostic settings are NOT removed by deleting the resource group
for SUB in $(az rest --method get \
  --url "https://management.azure.com/providers/Microsoft.Management/managementGroups/YOUR_MG_ID/descendants?api-version=2021-04-01" \
  --query "value[?type=='Microsoft.Management/managementGroups/subscriptions'].name" -o tsv); do
  az monitor diagnostic-settings subscription delete \
    --subscription "$SUB" --name "firefly-mg-diagnostics-$SUB" --yes
done
```

Then, common to both:

```shell
az ad sp delete --id YOUR_SP_CLIENT_ID
az role definition list --custom-role-only true -o table
```


# Google Cloud

**Scope: CLI and API only.** This guide covers the `gcloud` CLI and the Firefly API for onboarding GCP projects without the console wizard. Firefly also ships a Terraform module for Google Cloud onboarding, documented separately.

## When to use this

Use this guide to bulk onboard GCP projects, drive onboarding from a CI/CD pipeline, or enable org-level discovery. For a single project, the console wizard (**Settings > Integrations > Add New > Google Cloud**) is faster.

## Prerequisites

* Admin access to the Firefly console
* `gcloud` CLI, authenticated
* GCP IAM permissions to create service accounts and grant roles
* Org-level IAM permissions if you want folder-tree discovery (optional)
* `curl` and `jq`

## Pre-flight: can you create service account keys?

Run this before committing to a timeline. This integration depends on a downloadable service account JSON key, and some organizations block key creation with an org policy.

```shell
gcloud resource-manager org-policies describe \
  constraints/iam.disableServiceAccountKeyCreation \
  --project="$PROJECT_ID" --effective
```

If the constraint is enforced, key creation will fail and no amount of IAM permission will fix it. Options, in order of preference:

1. **Request a scoped exception** for the Firefly project only. Most platform teams will grant this for a single, audited service account — a narrower ask than disabling the policy org-wide.
2. **Use a project that's out of scope** of the policy, if you have one designated for third-party integrations.
3. **Contact your Firefly representative** to confirm whether a keyless option (Workload Identity Federation) is currently available for this integration.

Two related constraints worth checking at the same time, since both cause confusing failures later:

```shell
gcloud resource-manager org-policies describe \
  constraints/iam.disableServiceAccountKeyUpload \
  --project="$PROJECT_ID" --effective

gcloud resource-manager org-policies describe \
  constraints/iam.allowedPolicyMemberDomains \
  --project="$PROJECT_ID" --effective
```

The second restricts which identities can be granted roles and is a common cause of "role binding rejected" errors that look like a permissions problem but aren't.

## Phase A — Authenticate to Firefly

Create the key pair under **Settings > Users > Create Key Pair**, then:

```shell
FIREFLY_API="https://prodapi.firefly.ai/api"

TOKEN=$(curl -sS -X POST "${FIREFLY_API}/account/access_keys/login" \
  -H "Content-Type: application/json" \
  -d "{\"accessKey\":\"${FIREFLY_ACCESS_KEY}\",\"secretKey\":\"${FIREFLY_SECRET_KEY}\"}" \
  | jq -r '.access_token // .accessToken')
```

## Phase B — Configure Google Cloud

### 1. Authenticate and set the project

```shell
gcloud auth login
gcloud config set project PROJECT_ID

PROJECT_ID=$(gcloud config get-value project)
```

### 2. Create the service account

```shell
gcloud iam service-accounts create firefly-sa \
  --description="Service Account for Firefly integration" \
  --display-name="Firefly Service Account"

SA_EMAIL="firefly-sa@${PROJECT_ID}.iam.gserviceaccount.com"
echo "$SA_EMAIL"
```

Use a dedicated service account rather than reusing an existing one — it keeps revocation and audit simple.

### 3. Grant project-level roles

```shell
for ROLE in \
  roles/viewer \
  roles/iam.securityReviewer \
  roles/logging.configWriter \
  roles/storage.bucketViewer
do
  gcloud projects add-iam-policy-binding "$PROJECT_ID" \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="$ROLE" \
    --condition=None
done
```

| Role                         | Purpose                                                 |
| ---------------------------- | ------------------------------------------------------- |
| `roles/viewer`               | Read-only access for inventory discovery                |
| `roles/iam.securityReviewer` | IAM and security configuration, for compliance scanning |
| `roles/logging.configWriter` | Required for event-driven integration (log sinks)       |
| `roles/storage.bucketViewer` | Bucket metadata for IaC state discovery                 |

### 4. Grant conditional tfstate access

Object read access is scoped by an IAM condition so Firefly can only read objects whose name ends in `tfstate`.

```shell
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/storage.objectViewer" \
  --condition='title=TFStateSuffix,description=Limit access to tfstate objects only,expression=resource.name.endsWith("tfstate")'
```

**Use `add-iam-policy-binding`, never `set-iam-policy`, for this.** `set-iam-policy` overwrites the project's entire IAM policy document; `add-iam-policy-binding` is additive and safe.

### 5. Org-level folder discovery (optional)

Only needed if you want Firefly to discover the folder tree and auto-enroll projects. Requires org admin.

```shell
ORG_ID=$(gcloud organizations list --format="value(ID)")
ROLE_ID="fireflyFolderDiscovery"

gcloud iam roles create "$ROLE_ID" \
  --organization="$ORG_ID" \
  --title="Firefly Folder Discovery" \
  --description="Allows Firefly to discover the folder tree" \
  --permissions="resourcemanager.folders.get,resourcemanager.folders.list" \
  --stage="GA"

gcloud organizations add-iam-policy-binding "$ORG_ID" \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="organizations/${ORG_ID}/roles/${ROLE_ID}"
```

For full org-wide project discovery, also grant `roles/viewer` at the organization scope. This is the main scale lever on GCP — with org-level viewer and auto-discovery enabled, you onboard one anchor project and Firefly enumerates the rest.

### 6. Generate the service account key

```shell
gcloud iam service-accounts keys create firefly-sa-key.json \
  --iam-account="$SA_EMAIL"
```

This file is a long-lived credential. Keep it out of version control, delete it from your workstation once uploaded, and agree a rotation schedule up front.

**Service account keys don't expire.** That's a common finding in security reviews — the key is scoped to a dedicated read-only service account, the tfstate binding is conditioned to a filename suffix, and rotation is a process you control. To rotate, create a second key, update the integration in the Firefly console, then delete the old key:

```shell
gcloud iam service-accounts keys list --iam-account="$SA_EMAIL"
gcloud iam service-accounts keys delete KEY_ID --iam-account="$SA_EMAIL"
```

Agree a rotation interval during onboarding rather than after the first audit.

### 7. Enable required APIs

```shell
gcloud services enable \
  logging.googleapis.com \
  admin.googleapis.com \
  appengine.googleapis.com \
  bigquery.googleapis.com \
  cloudbilling.googleapis.com \
  cloudfunctions.googleapis.com \
  cloudscheduler.googleapis.com \
  dataproc.googleapis.com \
  dns.googleapis.com \
  cloudresourcemanager.googleapis.com \
  sqladmin.googleapis.com \
  compute.googleapis.com \
  iam.googleapis.com \
  container.googleapis.com \
  servicemanagement.googleapis.com \
  serviceusage.googleapis.com \
  cloudasset.googleapis.com \
  redis.googleapis.com \
  storage.googleapis.com \
  groupssettings.googleapis.com \
  spanner.googleapis.com \
  file.googleapis.com \
  recommender.googleapis.com
```

Takes 2–3 minutes. `recommender.googleapis.com` powers Google Cloud Insights — leaving it out silently disables that feature.

### 8. Additional projects (optional)

The same service account can cover multiple projects. For each additional project, repeat steps 3, 4, and 7 with `PROJECT_ID` set to the new project and `SA_EMAIL` unchanged:

```shell
for P in project-b project-c project-d; do
  for ROLE in roles/viewer roles/iam.securityReviewer roles/logging.configWriter roles/storage.bucketViewer; do
    gcloud projects add-iam-policy-binding "$P" \
      --member="serviceAccount:${SA_EMAIL}" --role="$ROLE" --condition=None
  done
done
```

## Phase C — Register with Firefly

```shell
SA_KEY=$(jq -c . firefly-sa-key.json | jq -R .)

PAYLOAD=$(jq -n \
  --arg name "Production GCP" \
  --arg projectId "$PROJECT_ID" \
  --argjson serviceAccountKey "$SA_KEY" \
  '{
    name: $name,
    projectId: $projectId,
    serviceAccountKey: $serviceAccountKey,
    isPrimary: true,
    shouldAutoDiscoverProjects: true,
    isProd: true,
    isEventDrivenDisabled: false,
    isIacAutoDiscoverDisabled: false,
    regexExcludeProjectsDiscovery: []
  }')

curl -sS -X POST "${FIREFLY_API}/integrations/google" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data "$PAYLOAD" | jq .
```

| Parameter                       | Description                                                                               |
| ------------------------------- | ----------------------------------------------------------------------------------------- |
| `name`                          | Display name for the integration                                                          |
| `projectId`                     | The GCP project ID being integrated. This is the anchor project used to discover the rest |
| `serviceAccountKey`             | Full contents of `firefly-sa-key.json`, as a JSON string                                  |
| `isPrimary`                     | True if this is your primary GCP integration                                              |
| `shouldAutoDiscoverProjects`    | Discover all accessible projects automatically                                            |
| `isProd`                        | Marks the integration as production                                                       |
| `isEventDrivenDisabled`         | `false` enables real-time event detection                                                 |
| `isIacAutoDiscoverDisabled`     | `false` enables automatic IaC discovery                                                   |
| `regexExcludeProjectsDiscovery` | Regex list of projects to skip, e.g. `[".*-test$", "sandbox-.*"]`                         |

The initially integrated project is listed first in the console, and every subsequently discovered project hangs off it. Deleting that first project deletes the whole integration — worth planning around before you tidy up unused projects.

This call isn't documented as idempotent. If a registration partially fails, check the console before retrying rather than assuming a second call will update the integration in place.

## Verify

1. Firefly console > **Settings > Integrations > Google Cloud**
2. Confirm the project appears and the status is connected
3. **Inventory**, filtered to Google Cloud — allow 10–15 minutes for first discovery

## Troubleshooting

| Symptom                              | Likely cause                                                                                                         |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| Key creation fails outright          | `constraints/iam.disableServiceAccountKeyCreation` is enforced — see the pre-flight check above                      |
| Role binding rejected                | Org policy restricting IAM grants (`allowedPolicyMemberDomains`), or missing `resourcemanager.projects.setIamPolicy` |
| API enablement fails                 | Billing not enabled on the project, or missing `serviceusage.services.enable`                                        |
| Registration returns 4xx             | Malformed `serviceAccountKey` (check the `jq -c . \| jq -R .` escaping), or an expired token                         |
| Some projects missing from Inventory | APIs not enabled on those projects, or they match an exclusion regex                                                 |
| No IaC state discovered              | The tfstate IAM condition wasn't applied, or state objects don't end in `tfstate`                                    |


# Integrations Overview

Firefly is most powerful when it's connected to the various platforms in your cloud ecosystem. Integrations allow Firefly to pull in data and also push out notifications or fixes. This section provides step-by-step guidance for integrating Firefly with different types of systems:

## Integration Categories

### Data Source Integrations

Firefly connects with various platforms to fetch real-time configuration data:

* Cloud Providers: [AWS](/integrations/data-sources/aws), [Azure](/integrations/data-sources/azure), [Google Cloud](/integrations/data-sources/google-cloud), [Kubernetes](/integrations/data-sources/kubernetes), [Oracle Cloud Infrastructure](/integrations/data-sources/oracle-cloud-infrastructure), [Nebius Cloud](/integrations/data-sources/nebius)
* Monitoring & Security: [Datadog](/integrations/data-sources/datadog), [New Relic](/integrations/data-sources/new-relic), [PagerDuty](/integrations/data-sources/pagerduty)
* Identity & Access: [Okta](/integrations/data-sources/okta), [Hashicorp Vault](/integrations/data-sources/hashicorp-vault)
* DNS & CDN: [Cloudflare](/integrations/data-sources/cloudflare), [Akamai](/integrations/data-sources/akamai), [NS1](/integrations/data-sources/ns1)
* Databases: [MongoDB Atlas](/integrations/data-sources/mongodb-atlas)

### Version Control Integrations

Firefly integrates with version control systems:

* [GitHub](/integrations/version-control/github)
* [GitLab](/integrations/version-control/gitlab)
* [Bitbucket](/integrations/version-control/bitbucket)
* [Azure DevOps](/integrations/version-control/azuredevops)
* [AWS CodeCommit](/integrations/version-control/codecommit)

### IaC Remote State Integrations

Firefly integrates with IaC state management platforms:

* [Terraform Cloud](/integrations/iac-remote-state/terraform-cloud)
* [env0](/integrations/iac-remote-state/env0)
* [Google Cloud Storage](/integrations/iac-remote-state/google-cloud-storage)
* [Hashicorp Consul](/integrations/iac-remote-state/hashicorp-consul)

### Notification Integrations

Firefly can send alerts and updates through various platforms:

* Chat & Collaboration: [Slack](/integrations/notifications/slack), [Microsoft Teams](/integrations/notifications/microsoft-teams), [Google Chat](/integrations/notifications/google-chat), [Webex](/integrations/notifications/webex)
* Alerting: [PagerDuty](/integrations/notifications/pagerduty), [OpsGenie](/integrations/notifications/opsgenie), [Torq](/integrations/notifications/torq)
* Webhooks: [Generic Webhook](/integrations/notifications/webhook)

### Project Management Integrations

Firefly can integrate with project management platforms :

* [Jira](/integrations/project-management/jira)
* [ServiceNow](/integrations/project-management/servicenow)

### Other Integrations

Firefly can integrate with other platforms:

* [Workflows with CI/CD](/integrations/workflows)
* [Backstage](/integrations/backstage)
* [MCP](/integrations/mcp)
* [Wiz](/detailed-guides/workflows/wiz-policy-integration): Delegate IaC policy evaluation for workspace runs to Wiz. Configured through a variable set rather than the Integrations page.

### Private Network Connectivity

For services that aren't reachable over the public internet — including self-hosted GitHub Enterprise Server, internal APIs, artifact repositories, and other VPC-hosted endpoints — Firefly supports private connectivity over AWS PrivateLink:

* [AWS PrivateLink](/integrations/aws-privatelink)

## Getting Started

Each integration follows a similar pattern (except for Workflow Integrations and Backstage):

1. Navigate to Settings > Integrations in Firefly's UI.
2. Click "Add New".
3. Follow the prompts specific to that integration type.

Firefly's documentation provides detailed instructions for each integration, which we summarize in the following sections.


# Integrating Data Sources

Firefly supports integrating certain data sources that includes Cloud providers, Saas platforms, and third-party platforms to include in your asset inventory and governance.

> **Note:** After adding a data source, it may take a few minutes for Firefly to initially fetch your assets. All assets are automatically refreshed every few hours to ensure your inventory remains up-to-date.

## Supported Data Sources

### Cloud Providers

* [AWS](/integrations/data-sources/aws)
* [Azure](/integrations/data-sources/azure)
* [Google Cloud](/integrations/data-sources/google-cloud)
* [Oracle Cloud Infrastructure](/integrations/data-sources/oracle-cloud-infrastructure)
* [Nebius Cloud](/integrations/data-sources/nebius)

### Monitoring & Observability

* [Datadog](/integrations/data-sources/datadog)
* [New Relic](/integrations/data-sources/new-relic)

### Identity & Security

* [Okta](/integrations/data-sources/okta)
* [HashiCorp Vault](/integrations/data-sources/hashicorp-vault)

### Infrastructure & Orchestration

* [Kubernetes](/integrations/data-sources/kubernetes)
* [Cloudflare](/integrations/data-sources/cloudflare)

### Databases

* [MongoDB Atlas](/integrations/data-sources/mongodb-atlas)

### Other Integrations

* [PagerDuty](/integrations/data-sources/pagerduty)
* [NS1](/integrations/data-sources/ns1)
* [GitHub](/integrations/data-sources/github)
* [Akamai](/integrations/data-sources/akamai)

## Request Additional Data Source Support

If you need integration with a data source that is not currently supported, please contact Firefly's support team via email at <help@firefly.ai>. When requesting a new data source integration, please provide details about the platform and your specific use case to help our team better understand your requirements.


# AWS

Amazon Web Services (AWS) integration can be set up using CloudFormation. This guide covers the setup process and best practices for integrating your AWS account with Firefly.

## Integration Methods

The integration creates a cross-account IAM Role with read-only access (security audit permissions) to your resources. The integration may also set up an Amazon SNS notification for tfstate file event-driven scanning.

### Using CloudFormation

Firefly offers two CloudFormation integration options:

* **Single Account Integration**: Use CloudFormation to integrate individual AWS accounts.
* **AWS Organization Integration**: Use CloudFormation StackSet to integrate multiple accounts across your AWS Organization.

You can download and review the template here: <https://infralight-templates-public.s3.amazonaws.com/config_template.yml>

#### Setup Procedure

1. Log in to AWS with permissions for CloudFormation and IAM.
2. Copy your AWS account ID from the AWS console.
3. In Firefly, go to **Settings > Integrations**.
4. Select **Add New > AWS**.
5. Select **Single Account Integration CloudFormation** or **AWS Organization CloudFormation**.
6. Paste your AWS account ID.
7. Select **Launch Stack**.

## Best Practices

1. Use a dedicated AWS account (or at least a separate IAM role) for Firefly's access.
2. Grant only the minimum read permissions (Firefly's provided template covers what's needed).
3. Monitor the Firefly integration user/role in AWS to ensure it's not being used elsewhere.

## Updating StackSet Template

If you're using AWS Organization integration with CloudFormation StackSet, follow these steps to update the template:

1. Log in to the management account AWS console.
2. Navigate to **CloudFormation > StackSets**.
3. Select **firefly-readonly-stackset**.
4. **Save your current configuration**: Copy and save the current target OU IDs in a note for reference.
5. Click **Actions > Edit StackSet details**.

### Wizard Page - Step 1: Choose a template

* Under **Prerequisite - Prepare template**, select **Replace current template**.
* In the **Amazon S3 URL** field, paste: `https://infralight-templates-public.s3.amazonaws.com/config_template.yml`
* Click **Next**.

### Wizard Page - Step 2: Specify StackSet details

* Keep all settings the same.
* Click **Next**.

### Wizard Page - Step 3: Configure StackSet options

* Under **Capabilities**, check **I acknowledge...**.
* Click **Next**.

### Wizard Page - Step 4: Set deployment options

* **Organizational units (OUs)**: Enter the same AWS OU IDs you saved earlier.
* **Specify Regions**: Select the same region(s) as before.
* **Deployment options**:
  * **Maximum concurrent accounts**: Change to **Percentage** with value **100**.
  * **Concurrency mode**: Select **Soft failure tolerance**.
* Click **Next**.
* Review and click **Submit** to complete the update.

## AWS Discovery Status

To scan your integration for changes:

1. Go to **Settings > Integrations > AWS**.
2. Find the integration you want to scan.
3. For assets changes, on the integration menu, select **Scan Assets**.
4. For IaC stacks changes, on the integration menu, select **Scan Stacks**.
5. View changes in the Inventory and/or IaC Explorer after several minutes.


# Azure

Firefly integrates with Microsoft Azure to pull in information about your cloud resources—such as virtual machines, storage accounts, and databases—directly into your Firefly Inventory. This enables you to view, manage, and govern Azure assets alongside resources from other cloud providers. You can use Firefly to enforce infrastructure-as-code (IaC) practices and apply policies across your Azure environment, helping ensure compliance, visibility, and best practices at scale.

## Best Practices

1. Ensure the service principal has read access to all resource groups you want scanned.
2. Use dedicated service principals for Firefly's access rather than sharing with other applications.
3. For governance, mark certain subscriptions as production during integration (Firefly has a "Mark as Production" checkbox for each integration which you should tick for your production accounts).
4. Monitor the Firefly service principal in Azure to ensure it's not being used elsewhere.

## Integration Methods

### Using ARM Template

ARM Template is the recommended method for Azure integration as it provides automated deployment through the Azure Portal.

#### Prerequisites

* Ensure you have appropriate permissions in Azure to deploy ARM templates.
* Access to the Azure Portal.
* Proper access to the subscriptions or management groups you want to integrate.

#### Setup Procedure

1. In Firefly, go to **Settings > Integrations > Add New > Azure**.
2. Select your integration method:
   * **Individual Subscriptions** > **ARM Template** (Recommended)
   * **Management Group (Auto-Discover)** > **ARM Template**
3. Click **Deploy to Azure** to open the ARM template in the Azure Portal.
4. Generate a Firefly API Key by clicking **Generate API Key** in Firefly.
5. Copy the key and paste it into the ARM template as instructed.
6. Follow the instructions in the Azure Portal to complete the deployment.

### Using PowerShell

Firefly also provides a PowerShell onboarding script: [gofireflyio/ps-firefly-azure-onboarding](https://github.com/gofireflyio/ps-firefly-azure-onboarding). It creates the app registration and service principal Firefly needs, assigns the standard read-only, Billing Reader (cost optimization), and Security Center roles, and can read `.tfstate`-suffixed blobs. Each of these can be toggled off individually (`$enableActiveDirectory`, `$enableCostOptimization`, `$enableSecurityCenterResources`).

## Azure Discovery Status

To scan your integration for changes and discover new assets:

### Procedure

1. Go to **Settings > Integrations > Azure**.
2. Find the integration you want to scan.
3. For assets changes, on the integration menu, select **Scan Assets**.
4. For IaC stacks changes, on the integration menu, select **Scan Stacks**.
5. View changes in the Inventory and/or IaC Explorer after several minutes.


# Google Cloud

Firefly integrates with Google Cloud to ingest information about your cloud resources into your Firefly Inventory. This enables you to view, manage, and govern Google Cloud assets alongside resources from other cloud providers. You can use Firefly to enforce infrastructure-as-code (IaC) practices and apply policies across your Google Cloud environment, helping ensure compliance, visibility, and best practices at scale.

### Google Cloud Insights

After integrating your Google Cloud account, we retrieve Google Cloud Insights directly from your projects. These insights identify potential risks in your asset configurations, enhance your security posture, and reveal significant patterns in resource usage. To utilize this feature, verify you have enabled the Recommender API.

### Multiple Projects

Firefly can discover multiple Google Cloud projects under one integration if the service account is given organization-level viewer rights. If you prefer to integrate each project separately, use separate service accounts or keys for isolation. In the Firefly UI, each integration will be listed by the project or alias name you give.

## Service Account Key

> **This page covers the data source integration** — the read-only credentials Firefly uses to discover your Google Cloud assets into the Inventory. It is separate from the credentials your Firefly runs use to provision infrastructure. To let runs authenticate to Google Cloud without a stored service account key, see [Google Cloud OIDC Integration](/detailed-guides/oidc-provider/google-cloud).

### Creating a service account

1. Go to your Google Cloud service account, and click **Create Service Account**.
2. Enter the Service account details, and click **Create and Continue**.
3. Add the roles below:

   * viewer
   * iam.securityReviewer
   * logging.configWriter (to enable event-driven integration)
   * storage.bucketViewer
   * storage.objectViewer (conditional to `tfstate` suffix)

   To add the `tfstate` condition that enables Firefly to scan only files with a `tfstate` suffix:

   1. Click **Add IAM Condition**.
   2. Enter the Title and Condition type > **Resource** > **Name**.
   3. **Operator** > **Ends with**.
   4. Under **Value**, enter `tfstate` > **Save** > **Done**.
4. At the organization level, create a custom role that allows Firefly to discover the project folder tree. Attach this role to your service account:
   1. Click your organization level.
   2. Click **Roles** > **Create Role**.
   3. Enter a Title and ID.
   4. Under **Role launch stage**, click **General Availability**.
   5. Click **Add Permissions** and add the permissions below:
      * resourcemanager.folders.get
      * resourcemanager.folders.list
   6. Click **Add** > **Create**.
   7. Click **IAM** > **Grant Access**.
   8. Under **New principals**, enter Firefly's principal.
   9. Under **Assign roles**, select the role you just created > **Save**.
5. At the project level, click **Service Accounts** and select the Firefly service account.
6. Click the menu > **Manage keys** > **Add Key** > **Create new key**.
7. Click **JSON** > **Create**.
8. Selecting **Create** downloads a service account key file.
9. In Firefly, paste or upload the account key file into the Service Account Key field.

### Enabling APIs

To allow Firefly to scan your projects and present your assets in the Inventory, enable the APIs below:

* Logging API (to enable event-driven integration)
* Admin SDK API
* App Engine Admin API
* BigQuery API
* Cloud Billing API
* Cloud Functions API
* Cloud Scheduler API
* Cloud Dataproc API
* Cloud DNS API
* Cloud Resource Manager API
* Cloud SQL Admin API
* Compute Engine API
* IAM API
* Kubernetes Engine API
* Service Management API
* Service Usage API
* Cloud Asset API
* Google Cloud Memorystore for Redis API
* Cloud Storage API
* Groups Settings API
* Cloud Spanner API
* Google Cloud Filestore API
* Recommender API

### Discovering multiple projects in this integration

Use the same service account key to simultaneously integrate multiple Google Cloud projects.

1. Log in to the Google Cloud console.
2. Click **IAM & Admin** > **Service Accounts**.
3. Copy the principal of the Service account you created in [Creating a service account](#creating-a-service-account) (associated email address).
4. Select a resource, the desired project you would like to integrate or the organization if you want Firefly to discover all the projects in your organization.
5. Click **IAM** > **Grant Access**.
6. In the New principals field, paste the principal you copied in step 3.
7. In the role field, select the following roles and **Save**:
   * roles/iam.securityReviewer
   * roles/storage.objectViewer (conditional to `tfstate` suffix)
   * roles/viewer
   * roles/logging.configWriter
8. To exclude projects under this service account, enter the rules in the **Regex rules** field.
9. For all integrated projects, verify the Enabling APIs are activated.

## Google Cloud Discovery Status

To scan your integration for changes and discover new assets:

### Procedure

1. Select **Settings > Integrations > Google Cloud**.
2. Select the integration.
3. For assets changes, on the integration menu, select **Scan Assets**.
4. For IaC stacks changes, on the integration menu, select **Scan Stacks**.
5. View changes in the Inventory and/or IaC Explorer after several minutes.

The project that was initially integrated is the first one listed in the table. We use this project to discover all subsequent ones, which appear below it.

> **Warning:** Deleting the initial project deletes this integration, including all projects listed in the table.


# Oracle Cloud Infrastructure

Firefly integrates with Oracle Cloud Infrastructure to pull in information about your cloud resources—such as compute instances, object storage, databases etc. Directly into your Firefly Inventory. This enables you to view, manage, and govern OCI assets. You can use Firefly to enforce infrastructure-as-code (IaC) practices and apply policies across your OCI environment, helping ensure compliance, visibility, and best practices at scale.

## Best Practices

1. For governance, mark certain compartments as production during integration (Firefly has a "Mark as Production" checkbox for each integration which you should tick for your production accounts).
2. Use a dedicated OCI user for Firefly's access rather than sharing with other applications.

## Integration Methods

* [ORM Stack](#using-orm-stack) Creates a service user with read access to your OCI resources and optionally configures audit log streaming via Service Connector Hub.

### Using ORM Stack

ORM Stack (Oracle Resource Manager) is the recommended method for OCI integration as it provides automated deployment through the OCI Console.

**Note:** The ORM stack should be deployed in your tenancy's home region.

#### Prerequisites

* Ensure you have appropriate permissions in OCI to deploy ORM stacks.
* Access to the OCI Console.
* Proper access to the compartments or tenancy you want to integrate.

#### Setup Procedure

1. Log in to your desired OCI Tenancy with permission to create ORM Stack and IAM OCI resources.
2. In Firefly, go to **Settings > Integrations**.
3. Select **Add New > OCI**.
4. Enter your **OCI Tenancy** details.
5. Click **Generate API Key** to create a Firefly API key. Copy the key and paste it into the OCI Stack configuration.
6. (Optional) Expand **Advanced Options** to configure:
   * **Domain ID** — Specify the identity domain for user and group management.
   * **Compartment ID** — Specify the compartment for Firefly resources. If left empty, a "Firefly" compartment is auto-created.
   * **Service Connector Management** — Enable Firefly to manage audit log streaming via Service Connector Hub.
7. (Optional) Select **Mark as Production** to flag this account as production in Firefly. You can edit this at any time in the Integrations window.
8. (Optional) Select **Subscribed regions** to scan all subscribed regions, or uncheck to specify specific regions.
9. Click **Deploy to OCI** to open the ORM Stack in the OCI Console, and follow the instructions to deploy the stack.
10. Complete the stack deployment in the OCI Console.
11. Firefly will wait for the initiation of the connection and finish the integration process.

#### Created Resources

The ORM stack creates the following OCI resources:

* **IAM User** (`firefly-svc`) — Service user for Firefly authentication.
* **IAM Group** (`firefly-svc-admin`) — Group for managing Firefly user permissions.
* **IAM User Group Membership** — Adds the Firefly user to the admin group.
* **API Key** — API key pair for the Firefly service user.
* **IAM Dynamic Group** (`firefly-dynamic-group`) — For service connector permissions.
* **IAM Policy** (`firefly-svc-policy`) — Comprehensive permissions for Firefly access.
* **Service Connector Hub** (`firefly-audit-connector`) — Routes audit logs to Firefly's stream (optional).

#### IAM Policies

The integration creates an IAM policy (`firefly-svc-policy`) with the following permissions:

* **Global Read Access** — Allows Firefly to discover and inventory all OCI resources in your tenancy.
* **Service Connector Management** — Allows creation and management of Service Connector Hub resources in the Firefly compartment.
* **Stream Push Permissions** — Enables pushing audit logs to Firefly's managed streams for processing and analysis.

#### Compartment Management

If no compartment is specified during deployment, the stack automatically creates a new compartment named "Firefly" in your tenancy root for application resources (service connectors, audit log configurations).

**Note:** Identity resources (users, groups, policies, dynamic groups) are always created in the root tenancy, regardless of the compartment setting. This is an OCI requirement.

#### Event-Driven Integration

The integration optionally configures audit log streaming via OCI Service Connector Hub for real-time event-driven scanning. When enabled, service connectors capture audit events across multiple categories—including compute, networking, storage, IAM, and database operations—and stream them to Firefly for analysis and monitoring.

Service connectors can be deployed across multiple OCI regions. The target stream is automatically selected based on your OCI region through Firefly's API.

## OCI Discovery Status

To scan your integration for changes and discover new assets on-demand:

### Procedure

1. Go to **Settings > Integrations > OCI**.
2. Find the integration you want to scan.
3. For assets changes, on the integration menu, select **Scan Assets**.
4. For IaC stacks changes, on the integration menu, select **Scan Stacks**.
5. View changes in the Inventory and/or IaC Explorer after several minutes.


# Nebius Cloud

Firefly integrates with Nebius Cloud to pull in information about your cloud resources—such as compute instances, GPU clusters, Kubernetes node groups, PostgreSQL clusters, container registries, and more—directly into your Firefly Inventory. This enables you to view, manage, and govern Nebius assets. You can use Firefly to enforce infrastructure-as-code (IaC) practices and apply policies across your Nebius environment, helping ensure compliance, visibility, and best practices at scale.

## Best Practices

1. For governance, mark your production integrations using the "Mark as Production" option during setup (or edit this setting later in the Integrations window).
2. Use a dedicated Nebius service account for Firefly's access rather than sharing with other applications.
3. Store Firefly API credentials securely using environment variables or a secrets manager.

## Integration Method

Nebius integration is performed using a Terraform module that creates the necessary IAM resources and registers the integration with Firefly.

* [Terraform Module](#using-terraform-module) Creates a service account with read access to your Nebius resources and optionally configures audit log permissions for event-driven integration.

### Using Terraform Module

The Terraform module is the recommended method for Nebius integration as it provides automated, repeatable deployment that fits into your existing IaC workflows.

#### Prerequisites

* **Terraform** >= 1.5.0 installed
* **Nebius CLI** installed and configured ([Installation Guide](https://docs.nebius.com/cli/install))
* **Firefly Credentials** (access key and secret key from Firefly console)
* IAM admin permissions in your Nebius tenant (to create service accounts and access permits)

#### Setup Procedure

1. Log in to your Nebius tenant with permissions to create IAM resources.
2. In Firefly, go to **Settings > Integrations**.
3. Select **Add New > Nebius**.
4. Enter your **Tenant ID** and **Project ID** (see [Getting Your IDs](#getting-your-ids) below).
5. (Optional) Enter an **Integration Name** to customize how this integration appears in Firefly.
6. (Optional) Select **Mark as Production** to flag this account as production in Firefly.
7. (Optional) Select **Enable Event-Driven** to enable audit log permissions for real-time event-driven scanning.
8. Click **Generate Terraform Snippet** to create the module configuration.
9. Copy the generated Terraform snippet to a new file (e.g., `main.tf`).
10. Configure Nebius authentication (see [Authentication Methods](#nebius-authentication-methods) below).
11. Run `terraform init && terraform plan && terraform apply`.
12. Once the Terraform apply completes, Firefly will automatically detect the integration and begin scanning your resources.

#### Getting Your IDs

Use the Nebius CLI to retrieve your Tenant ID and Project ID:

```bash
# Get tenant ID
nebius iam tenant list

# Get project ID (replace <tenant-id> with your tenant ID)
nebius iam project list --parent-id <tenant-id>
```

#### Nebius Authentication Methods

The Terraform module supports three authentication methods for running the onboarding:

**Option 1: Environment Variables (Recommended for CI/CD)**

Set the following environment variables before running Terraform:

```bash
export NB_SA_ID="serviceaccount-xxxxxxxxxxxx"
export NB_SA_PUBLIC_KEY_ID="publickey-xxxxxxxxxxxx"
export NB_SA_PRIVATE_KEY_FILE="/path/to/private.pem"
```

In your Terraform configuration:

```hcl
nebius_auth_method = "env"
```

**Option 2: Direct Credentials**

Specify credentials directly in the Terraform module:

```hcl
nebius_auth_method        = "service_account"
nebius_service_account_id = "serviceaccount-xxxxxxxxxxxx"
nebius_public_key_id      = "publickey-xxxxxxxxxxxx"
nebius_private_key_file   = "/path/to/private.pem"
```

**Option 3: CLI Profile (Local Development)**

Use an existing Nebius CLI profile:

```hcl
nebius_auth_method = "profile"
nebius_profile     = "myprofile"
```

#### Creating Nebius Admin Credentials

If you need to create new admin credentials for running the Terraform module:

```bash
# Create service account with admin permissions
nebius iam service-account create --name firefly-admin-sa --parent-id <project-id>

# Get service account ID
export SA_ID=$(nebius iam service-account get-by-name \
  --name firefly-admin-sa --format json | jq -r ".metadata.id")

# Add to admin group (replace <admin-group-id> with your admin group)
nebius iam group-membership create --parent-id <admin-group-id> --member-id $SA_ID

# Generate authorized key
nebius iam auth-public-key generate --service-account-id $SA_ID \
  --output ~/nebius-admin-key.json

# Extract credentials for environment variables
export NB_SA_ID=$(cat ~/nebius-admin-key.json | jq -r '.["subject-credentials"].iss')
export NB_SA_PUBLIC_KEY_ID=$(cat ~/nebius-admin-key.json | jq -r '.["subject-credentials"].kid')
cat ~/nebius-admin-key.json | jq -r '.["subject-credentials"]["private-key"]' > ~/nebius-admin.pem
export NB_SA_PRIVATE_KEY_FILE=~/nebius-admin.pem
```

#### Terraform Module Example

```hcl
module "firefly_nebius_onboarding" {
  source = "github.com/gofireflyio/firefly-nebius-onboarding?ref=main"

  # Required
  tenant_id          = "tenant-xxxxxxxxxxxx"
  project_id         = "project-xxxxxxxxxxxx"
  firefly_access_key = var.firefly_access_key
  firefly_secret_key = var.firefly_secret_key

  # Nebius Authentication - choose one method:

  # Option 1: Environment variables (default, recommended for CI/CD)
  # Set: NB_SA_ID, NB_SA_PUBLIC_KEY_ID, NB_SA_PRIVATE_KEY_FILE
  nebius_auth_method = "env"

  # Option 2: Direct credentials
  # nebius_auth_method        = "service_account"
  # nebius_service_account_id = "serviceaccount-xxxxxxxxxxxx"
  # nebius_public_key_id      = "publickey-xxxxxxxxxxxx"
  # nebius_private_key_file   = "/path/to/private.pem"

  # Option 3: CLI profile (local development)
  # nebius_auth_method = "profile"
  # nebius_profile     = "myprofile"

  # Optional
  # integration_name  = "My Nebius Integration"
  # is_prod           = true
  # enable_audit_logs = true
}
```

#### Module Variables

**Required Variables**

| Variable             | Description                                             |
| -------------------- | ------------------------------------------------------- |
| `tenant_id`          | Nebius Tenant ID                                        |
| `project_id`         | Nebius Project ID where service account will be created |
| `firefly_access_key` | Firefly access key (from Settings > Access Keys)        |
| `firefly_secret_key` | Firefly secret key                                      |

**Optional Variables**

| Variable                      | Default     | Description                                          |
| ----------------------------- | ----------- | ---------------------------------------------------- |
| `integration_name`            | Tenant name | Custom integration name in Firefly                   |
| `prefix`                      | `""`        | Prefix for created resource names                    |
| `suffix`                      | `""`        | Suffix for created resource names                    |
| `existing_service_account_id` | `null`      | Use existing service account instead of creating new |
| `existing_group_id`           | `null`      | Use existing group instead of creating new           |
| `is_prod`                     | `true`      | Mark integration as production environment           |
| `enable_audit_logs`           | `true`      | Enable audit log permissions for event-driven        |
| `skip_integration_request`    | `false`     | Skip Firefly API registration (for testing)          |

#### Created Resources

The Terraform module creates the following resources in your Nebius tenant:

| Resource         | Name                             | Description                                        |
| ---------------- | -------------------------------- | -------------------------------------------------- |
| Service Account  | `firefly-integration`            | Used by Firefly to access your environment         |
| Group            | `firefly-group`                  | Contains the service account                       |
| Group Membership | —                                | Links service account to group                     |
| Access Permit    | `viewer`                         | Read-only access on tenant for inventory discovery |
| Access Permit    | `auditlogs.audit-event-viewer`   | View audit logs (if event-driven enabled)          |
| Access Permit    | `auditlogs.audit-event-exporter` | Export audit logs (if event-driven enabled)        |
| Auth Public Key  | —                                | RSA key pair for service account authentication    |

#### IAM Permissions

The integration creates the following access permits:

* **Viewer Role** — Allows Firefly to discover and inventory all Nebius resources in your tenant, including compute instances, GPU clusters, Kubernetes resources, databases, and storage.

When event-driven integration is enabled:

* **Audit Log Viewer** — Allows reading audit log events for real-time change detection.
* **Audit Log Exporter** — Allows exporting audit log events to Firefly for processing and analysis.

#### Event-Driven Integration

When `enable_audit_logs` is set to `true` (default), the integration configures audit log permissions for real-time event-driven scanning. This enables Firefly to detect changes in your Nebius environment as they happen, providing faster drift detection and inventory updates.

## Nebius Discovery Status

To scan your integration for changes and discover new assets on-demand:

### Procedure

1. Go to **Settings > Integrations > Nebius**.
2. Find the integration you want to scan.
3. For asset changes, on the integration menu, select **Scan Assets**.
4. For IaC stacks changes, on the integration menu, select **Scan Stacks**.
5. View changes in the Inventory and/or IaC Explorer after several minutes.

## Policy Evolution

The Terraform module uses versioned policies (`policy_version` output) to track permission changes over time. When Firefly requires additional permissions in the future, you can update the module version and re-apply to get the new policy.

## Additional Resources

* [Firefly Nebius Onboarding Module](https://github.com/gofireflyio/firefly-nebius-onboarding) — GitHub repository with full documentation
* [Nebius Cloud Documentation](https://docs.nebius.com) — Official Nebius documentation
* [Nebius CLI Installation](https://docs.nebius.com/cli/install) — Guide to installing the Nebius CLI


# VMware vSphere

Firefly integrates with VMware vSphere to pull inventory from your vCenter environment — virtual machines, hosts, clusters, datastores, networks, folders, tags, and IAM — directly into your Firefly Inventory. This enables you to view, codify, and govern on-prem and hybrid-cloud workloads alongside your public cloud assets, applying the same IaC, policy, and drift detection practices across your entire estate.

## Best Practices

1. For governance, mark your production integrations using the "Mark as Production" option during setup (or edit later in the Integrations window).
2. Use a dedicated vCenter service account for Firefly with read-only permissions rather than sharing an existing admin account.
3. Store vCenter credentials securely — Firefly encrypts them at rest, but rotate the password periodically per your security policy.

## Integration Method

vSphere is typically deployed on-prem or in a private network not directly reachable from Firefly's cloud. Integration is performed via the Firefly UI, with connectivity established through the **Firefly Private Connector** (relay tunnel) when vCenter is not internet-exposed.

### Prerequisites

* **vCenter** 7.0 or later
* **vCenter service account** with read access to the inventory you want Firefly to scan (Datacenter, VM, Host, Datastore, Network, Tag read permissions)
* **Firefly Private Connector** deployed in the network where vCenter is reachable — see [Firefly Private Connector](https://github.com/gofireflyio/firefly-private-connector) (required only if vCenter is not publicly reachable)
* **Network access** from the connector host to vCenter on port 443

### Setup Procedure

1. In Firefly, go to **Settings > Integrations**.
2. Select **Add New > vSphere**.
3. Enter the following fields:
   * **Name** — Integration name as it will appear in Firefly
   * **vCenter URL** — Hostname or relay endpoint (e.g. `https://vcenter.example.com` or `https://<tunnel-id>.relay.firefly.ai`)
   * **Username** — vCenter service account (e.g. `firefly-readonly@vsphere.local`)
   * **Password** — Service account password
   * **Mark as Production** *(optional)* — Flags this integration as a production environment in Firefly
4. Click **Save**. Firefly verifies the connection and begins scanning.
5. View discovered assets in the Inventory after several minutes.

### Editing Credentials

To rotate the password or update the vCenter URL:

1. Go to **Settings > Integrations > vSphere**.
2. On the integration menu, select **Edit**.
3. Update the relevant fields. The password is masked — re-enter it to update.
4. Click **Save**.

## Supported Resources

Firefly currently supports 27 vSphere resource types:

**Datacenter & Folder**

* `vsphere_datacenter`
* `vsphere_folder`

**Virtual Machine**

* `vsphere_virtual_machine`
* `vsphere_virtual_machine_snapshot`

**Datastore / Storage**

* `vsphere_datastore_cluster`
* `vsphere_vmfs_datastore`
* `vsphere_nas_datastore`
* `vsphere_vm_storage_policy`

**Network**

* `vsphere_distributed_virtual_switch`
* `vsphere_distributed_port_group`
* `vsphere_host_port_group`
* `vsphere_host_virtual_switch`

**Compute**

* `vsphere_compute_cluster`
* `vsphere_resource_pool`
* `vsphere_host`
* `vsphere_vapp_container`
* `vsphere_compute_cluster_vm_group`
* `vsphere_compute_cluster_host_group`
* `vsphere_compute_cluster_vm_affinity_rule`
* `vsphere_compute_cluster_vm_anti_affinity_rule`

**Tag**

* `vsphere_tag`
* `vsphere_tag_category`
* `vsphere_custom_attribute`

**IAM**

* `vsphere_role`
* `vsphere_entity_permissions`

**Content Library**

* `vsphere_content_library`
* `vsphere_content_library_item`

## vSphere Discovery Status

To scan your integration for changes and discover new assets on-demand:

### Procedure

1. Go to **Settings > Integrations > vSphere**.
2. Find the integration you want to scan.
3. For asset changes, on the integration menu, select **Scan Assets**.
4. For IaC stacks changes, on the integration menu, select **Scan Stacks**.
5. View changes in the Inventory and/or IaC Explorer after several minutes.

## Event-Driven Integration

Firefly polls the vCenter Events API to detect changes in your vSphere environment (VM lifecycle, power state, cluster events). A watermark mechanism ensures no events are missed or duplicated between polls.

## Codification

vSphere resources discovered in Inventory can be codified into Terraform using the [VMware vSphere Terraform provider](https://registry.terraform.io/providers/vmware/vsphere/latest/docs). Select an unmanaged vSphere resource in Inventory and choose **Codify** to generate the corresponding Terraform configuration.

## Additional Resources

* [VMware vSphere Terraform Provider](https://registry.terraform.io/providers/vmware/vsphere/latest/docs)
* [Firefly Private Connector](https://github.com/gofireflyio/firefly-private-connector) — Relay setup for on-prem vCenter
* [vCenter Documentation](https://docs.vmware.com/en/VMware-vSphere/index.html)


# Kubernetes

Integrating a Kubernetes cluster involves deploying a Firefly agent (container) in your cluster that reports resource info. In Firefly, select Add New > Kubernetes. You'll be prompted for a Cluster ID (an alias or name to identify the cluster) and whether to mark it as production. You can also choose to integrate Argo CD if you use it for GitOps (Firefly will then fetch additional data about the cluster's apps).

On the next step, Firefly will provide a command, a Helm install command that includes a manifest URL and an API token – which you run in your K8s cluster's context. This command installs Firefly's agent (often in the firefly namespace). The agent will collect cluster resources (Pods, Deployments, Services, etc.) and send them to Firefly.

If Argo CD integration was enabled, you'll also input your Argo CD domain and an API token for Argo in the Firefly setup, which allows Firefly to correlate Argo applications with cluster objects. Once done, Firefly will list your cluster in Inventory (under Kubernetes provider) and you'll see Kubernetes objects as part of your asset inventory.

For K8s, Firefly's drift and codification features can track the cluster's manifests similarly to cloud resources. The integration will continuously monitor the cluster (the agent watches for changes) and Firefly also periodically pulls. If you destroy the cluster or uninstall the agent, Firefly will mark those resources as deleted after a while.

## Prerequisites

* Access to a Kubernetes cluster with administrative privileges.
* `kubectl` or Helm installed and configured.
* Cluster context properly configured.
* (Optional) Argo CD installed if using GitOps.
* (Optional) AWS S3 bucket for Argo CD configuration (if using Argo CD).

## Setup Procedure

1. In Firefly, click **Settings > Integrations**.
2. Click **Add New > Kubernetes**.
3. Enter the Cluster ID (a unique alias).
4. (Optional) Select the Mark as Production checkbox.
5. (Optional) To display the Kubernetes object status from Argo CD in the Inventory, select the Integrate Argo CD checkbox (Currently supported by AWS only).
6. Click **Next**.

### Argo CD Integration (Optional)

If you are integrating with Argo CD, fill in the following fields:

* **Argo CD Domain**: The Argo CD server domain in your cluster.
* **Argo CD API Token**: We recommend creating a dedicated Argo CD user with read-only permissions, without admin permissions, and then create a token for the new user. See [Create New User](https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/#create-new-user) and [Generate Token](https://argo-cd.readthedocs.io/en/stable/user-guide/commands/argocd_account_generate-token/) in the Argo CD documentation.
* **AWS S3 Bucket**: Create a dedicated bucket in an AWS account integrated with Firefly for the Argo CD configuration output.
* **AWS S3 Bucket Region**: Select the region of the S3 account.

7. Click **Next**.
8. Copy the command, and run it in the terminal (this installs Firefly's agent in the firefly namespace).
9. Click **Done**.

## Configuration Details

* Firefly scans by default every 15 minutes. You can configure the frequency in the Helm install command.
* Your Kubernetes configurations list will stay updated automatically.
* You can enforce IaC or policies on your Kubernetes assets.
* Supports monitoring of Kubernetes resources.
* Supports drift detection and manifest tracking.
* Supports Argo CD integration for GitOps workflows.


# Akamai

Firefly integrates with Akamai to pull in information like configurations, properties, and edge hostnames as "assets". This means in your Firefly Inventory, you'll see Akamai resources listed (with their configurations) just like cloud assets. You can then enforce IaC or policies on them as well (for example, ensuring all Akamai properties follow a naming convention).

## Prerequisites

* An Akamai API client with appropriate credentials (Client Secret, Access Token, Client Token).
* The Host value for your Akamai API (usually found in your `.edgrc` file or Akamai Control Center).
* Ensure the API client has read permissions on Akamai resources.
* Access to Akamai Control Center to create API clients.

## Setup Procedure

1. In Firefly, click **Settings > Integrations** and then **Add New > Akamai**.
2. In Akamai Control Center, create a new API client with read permissions.
3. Copy the following credentials from your Akamai Control Center into Firefly's integration form:
   * **Nickname**: A name to identify this integration (e.g., "Akamai").
   * **Client Secret**: Your Akamai API client secret.
   * **Host**: The Akamai API host (e.g., `akab-xxxx.luna.akamaiapis.net`).
   * **Access Token**: Your Akamai API access token.
   * **Client Token**: Your Akamai API client token.
4. Click **Next**.
5. Click **Done**.

### Creating API Credentials

1. Navigate to Akamai Control Center [here](https://control.akamai.com).
2. Go to Identity & Access Management section.
3. Create a new API client with read-only permissions.
4. Save the client token, client secret, and access token.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your Akamai configurations list will stay updated automatically.
* You can enforce IaC or policies on your Akamai assets.
* Supports monitoring of Akamai properties, configurations, and edge hostnames.


# Datadog

Firefly integrates with Datadog to pull in information like monitors, dashboards, and alerts as "assets". This means in your Firefly Inventory, you'll see Datadog monitors listed (with their configurations) just like cloud assets. You can then enforce IaC or policies on them as well (for example, ensuring all monitors follow a naming convention).

## Prerequisites

* A Datadog Application Key from your Datadog account.
* A Datadog API Key from your Datadog account.
* Ensure both keys have read permissions on Datadog data (usually Admin or standard API key is fine since Datadog doesn't have granular read roles).
* Access to Datadog's API Keys and Application Keys sections.

## Setup Procedure

1. In Firefly, select **Settings > Integrations** and then **Add New > Datadog**.
2. Create a new application key [here](https://app.datadoghq.com/organization-settings/application-keys).
3. From the upper-right corner, select **New Key**.
4. Copy and paste the application key into the box.
5. Create a new API key [here](https://app.datadoghq.com/organization-settings/api-keys).
6. From the upper-right corner, select **New Key**.
7. Copy and paste the API key into the box.
8. Select your Datadog site and click **Next**.
9. Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your Datadog monitors list will stay updated automatically.
* You can enforce IaC or policies on your Datadog assets.
* Supports monitoring of Datadog monitors, dashboards, and alerts.


# New Relic

New Relic is a comprehensive observability platform that helps you monitor your applications, infrastructure, and user experience. This integration allows Firefly to include New Relic monitors and dashboards in your inventory.

## Prerequisites

* A New Relic account with administrative access.
* API key with appropriate permissions.
* Account number from your New Relic account.
* Access to New Relic API endpoints.
* Ability to create and manage API keys.

## Setup Procedure

1. Log in to your New Relic account.
2. In New Relic:
   * Select the account dropdown icon.
   * Navigate to **API keys**.
3. Copy your account number from the API keys section.
4. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > New Relic**.
   * Enter a descriptive name in the Nickname field.
   * Paste your account number into the Account ID field.
5. Back in New Relic:
   * Click **Create a key**.
   * Choose **User** as the Key type.
   * Enter a descriptive Name.
   * Click **Create a key**.
   * Click the more icon and choose **Copy key**.
6. Return to Firefly:
   * Paste the API key into the API Key field.
   * Select your Region.
   * Click **Next**.
   * Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your New Relic configurations list will stay updated automatically.
* You can enforce IaC or policies on your New Relic assets.
* Supports monitoring of New Relic monitors, dashboards, application metrics, and infrastructure data.


# Okta

Okta is an Identity Management solution that can be integrated with Firefly to fetch Okta applications, groups, and other assets for governance purposes. This integration enables you to ensure Okta apps have specific settings, maintain a unified view of SaaS app configurations, and monitor and govern your identity management assets.

## Prerequisites

* Okta account with administrative access.
* Ability to generate API tokens.
* Access to Okta API endpoints.
* Required API token permissions for:
  * Users
  * Applications
  * Groups

## Setup Procedure

### 1. Generate Okta API Token

1. Sign in to your Okta account.
2. Navigate to **API > Create Token**.
3. Enter a descriptive name in the Name field.
4. Click **Create Token**.
5. Copy the generated token.

### 2. Configure in Firefly

1. In Firefly, go to **Settings > Integrations**.
2. Click **Add New > Okta**.
3. Enter a descriptive name in the Nickname field.
4. Paste your API token into the API Token field.
5. Enter your Okta account URL in the Base URL field (e.g., dev-12345.okta.com).
6. Click **Next**.
7. Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your Okta configurations list will stay updated automatically.
* You can enforce IaC or policies on your Okta assets.
* Supports monitoring of Okta applications, groups, and user information.


# Entra ID

Firefly integrates with Microsoft Entra ID (formerly Azure AD) to pull in information about your directory resources—such as users, service principals, and app registrations—directly into your Firefly Inventory. This gives you a unified view of your identity assets alongside the rest of your cloud infrastructure, so you can govern who and what has access across your environment.

## Prerequisites

* A Microsoft Entra ID tenant.
* Permission to register an application in the tenant.
* Permission to grant admin consent for Microsoft Graph application permissions. This is a tenant-level action and typically requires a Global Administrator or Privileged Role Administrator.

## Setup Procedure

### 1. Register an Application in Entra ID

1. In the Azure Portal, go to [App registrations](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade).
2. Click **New registration**.
3. Enter a name for the application (for example, `firefly-app`).
4. Leave the default settings and click **Register**.
5. On the application's **Overview** page, copy the following values:
   * **Application (client) ID**
   * **Directory (tenant) ID**

### 2. Grant API Permissions

1. In the application, go to **API permissions**.
2. Click **Add a permission > Microsoft Graph > Application permissions**.
3. Add the `Directory.Read.All` permission.
4. Click **Grant admin consent** for your tenant.

Admin consent is required. Without it, Firefly cannot validate the connection even when the credentials are correct. If you do not hold a Global Administrator or Privileged Role Administrator role, ask someone who does to grant consent before continuing.

### 3. Create a Client Secret

Create the secret once permissions are in place. Its value is shown only once, so it is best generated immediately before you paste it into Firefly.

1. In the application, go to **Manage > Certificates & secrets**.
2. Click **New client secret**.
3. Set an expiry period and click **Add**.
4. Copy the secret **Value** immediately—it is not shown again.

> Copy the secret **Value**, not the Secret ID. These are different, and the Secret ID will not authenticate.

Make a note of the expiry date you set. When a client secret expires, Firefly can no longer scan your tenant—see [Rotating the Client Secret](#rotating-the-client-secret).

### 4. Configure in Firefly

1. In Firefly, go to **Settings > Integrations**.
2. Click **Add New > Entra ID**.
3. Enter your **Tenant ID** (the Directory (tenant) ID from step 1).
4. Enter your **Client ID** (the Application (client) ID from step 1).
5. Paste your **Client Secret** (the secret Value from step 3).
6. Enter an **Integration Name** to customize how this integration appears in Firefly.
7. Click **Next**.
8. Click **Done**.

On save, Firefly validates the credentials against the Microsoft Graph API and displays an error if the credentials are invalid or admin consent has not been granted. Once validated, Firefly triggers an initial scan of your tenant.

## Supported Assets

Firefly currently discovers three Entra ID asset types:

| Asset Type         | Identifier                  | Description                             |
| ------------------ | --------------------------- | --------------------------------------- |
| Users              | `azuread_user`              | Entra ID user accounts                  |
| Service Principals | `azuread_service_principal` | Service principal objects in the tenant |
| App Registrations  | `azuread_application`       | Applications registered in the tenant   |

Additional Entra ID resource types—covering identity, credentials, ownership, and governance objects—are planned.

> Asset type identifiers use the `azuread_` prefix, matching the naming used by the underlying Microsoft provider. This is expected and does not indicate a stale or misconfigured integration.

## Discovered Assets

Entra ID assets appear in your Inventory with the **Discovered** status.

Discovered means Firefly has found the asset in your tenant and indexed it, but has not evaluated it against Infrastructure-as-Code. It sits alongside the other inventory states—Managed, Unmanaged, Drifted, and Ghost.

Because Discovered assets are not evaluated against IaC, these fields are intentionally empty for them:

* Drift status
* IaC type
* VCS repository and stack

> Empty drift, IaC, and VCS fields on Entra ID assets are expected behavior, not a data problem.

## Configuration Details

* Firefly scans your Entra ID tenant on a scheduled interval, and your inventory stays updated automatically.
* Only one integration per Entra ID tenant is supported for each Firefly account. Connecting the same tenant twice is rejected.
* Credentials are encrypted at rest.

## Scanning On Demand

To scan your integration for changes and discover new assets on demand:

1. Go to **Settings > Integrations > Entra ID**.
2. Find the integration you want to scan.
3. On the integration menu, select **Scan Assets**.
4. View changes in the Inventory after several minutes.

## Rotating the Client Secret

Client secrets in Entra ID expire based on the expiry period set when they were created. When a secret expires, Firefly can no longer authenticate and scans will begin to fail.

To rotate the secret:

1. In the Azure Portal, open the same app registration and go to **Manage > Certificates & secrets**.
2. Click **New client secret**, set an expiry, and click **Add**.
3. Copy the new secret **Value**.
4. In Firefly, go to **Settings > Integrations > Entra ID**.
5. On the integration menu, select **Edit**.
6. Paste the new secret and click **Save**.

> Set a reminder ahead of your client secret's expiry date. Firefly cannot scan your tenant with an expired secret.

## Limitations

* **Three asset types** are supported today—users, service principals, and app registrations. Other directory objects are not yet discovered.
* **No drift detection** for Entra ID assets. They are indexed for visibility and governance but are not evaluated against IaC.
* **No codification** of Entra ID assets.
* **One tenant per integration.** Connect additional tenants as separate integrations.

## Troubleshooting

| Symptom                                          | Resolution                                                                                                                                                                                          |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Credentials rejected on save                     | Confirm you pasted the secret **Value** and not the Secret ID. Confirm the Tenant ID is the *Directory (tenant) ID* and the Client ID is the *Application (client) ID*—these are easy to transpose. |
| Credentials appear correct but validation fails  | Confirm **Grant admin consent** was clicked for the tenant after adding `Directory.Read.All`.                                                                                                       |
| Integration worked previously and is now failing | The client secret has most likely expired. See [Rotating the Client Secret](#rotating-the-client-secret).                                                                                           |
| Connected successfully but no assets appear      | Confirm `Directory.Read.All` was both added and consented, then allow a few minutes for the first scan to complete.                                                                                 |
| Duplicate tenant rejected                        | An Entra ID integration already exists for that tenant in this Firefly account. Check your existing integrations.                                                                                   |
| Drift, IaC, or VCS columns are empty             | Expected behavior—see [Discovered Assets](#discovered-assets).                                                                                                                                      |

## Additional Resources

* [Microsoft Entra ID Documentation](https://learn.microsoft.com/en-us/entra/identity/) — Official Microsoft documentation
* [Register an application with Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) — Microsoft app registration guide
* [Cloud Asset Inventory](/key-features/cloud-asset-inventory) — How Firefly classifies and displays discovered assets


# GitHub

Firefly integrates with GitHub to pull in information about your repositories, organizations, and related assets. This integration allows you to manage and monitor your GitHub resources as part of your Firefly Inventory, enabling you to enforce policies and maintain consistency across your GitHub assets.

## Prerequisites

* A GitHub account with appropriate permissions.
* A Personal Access Token (PAT) with the required scopes.
* Access to the GitHub organizations you want to integrate.

## Setup Procedure

1. Log in to your GitHub account.
2. Generate a Personal Access Token by visiting [GitHub's token creation page](https://github.com/settings/tokens/new) with the following scopes:

### Repository Scopes

* `repo:status`
* `repo_deployment`
* `repo:invite`
* `public_repo`
* `security_events`

### Organization Scopes

* `read:org`

### Public Key Scopes

* `read:public_key`

### Repository Hook Scopes

* `read:repo_hook`
* `notifications`

### User Scopes

* `read:user`
* `user:email`

### Discussion Scopes

* `read:enterprise`

### GPG Key Scopes

* `read:gpg_key`

3. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > GitHub**.
   * Paste your Personal Access Token into the Access Token field.
   * Click **Next**.
   * Enter a descriptive name in the Nickname field.
   * Select the desired Organization.
   * Click **Next**.
   * Click **Done**.

### Creating a Personal Access Token

1. Go to [GitHub.com](https://github.com) and log in to your account.
2. Click your profile picture > **Settings**.
3. Scroll down to **Developer settings** (bottom left).
4. Select **Personal access tokens > Tokens (classic)**.
5. Click **Generate new token > Generate new token (classic)**.
6. Give your token a descriptive name.
7. Select the required scopes as listed above.
8. Click **Generate token**.

> **Note**: Copy the token immediately as you won't be able to see it again.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your GitHub repositories list will stay updated automatically.
* You can enforce IaC or policies on your GitHub assets.
* Supports monitoring of GitHub repositories, organizations.
* Your Personal Access Token is stored securely and encrypted.


# Cloudflare

Firefly integrates with Cloudflare to ingest DNS and CDN configurations, allowing you to view and manage your Cloudflare resources as part of your unified Firefly Inventory. This enables you to apply governance, enforce policies, and gain visibility into your Cloudflare assets alongside other cloud and infrastructure resources.

## Prerequisites

* A Cloudflare account with administrative access.
* Ability to generate API tokens.
* Access to Cloudflare API endpoints.
* API token with read permissions to your zones.

## Setup Procedure

1. Log in to your Cloudflare account.
2. Create an API token:
   * Visit [Cloudflare API Token Creation](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/).
   * Select the "Read all resources" template.
   * Copy the token.
3. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > Cloudflare**.
   * Enter a descriptive name in the Nickname field.
   * Paste the token into the API Token field.
   * Click **Next**.
   * Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your Cloudflare configurations list will stay updated automatically.
* You can enforce IaC or policies on your Cloudflare assets.
* Supports monitoring of Cloudflare DNS, CDN configurations and more.


# NS1

Firefly integrates with NS1 to pull in information about your DNS records and zones as "assets". This means in your Firefly Inventory, you'll see NS1 DNS records listed (with their configurations) just like cloud assets. You can then enforce IaC or policies on them as well (for example, ensuring all DNS records follow a naming convention).

## Prerequisites

* An NS1 account with administrative access.
* An NS1 API key with appropriate permissions.
* Access to NS1 API endpoints.
* Ability to manage API keys.

## Setup Procedure

1. Log in to your NS1 account.
2. Create an API Key by following the instructions in the [NS1 API Key Management Guide](https://help.ns1.com/hc/en-us/articles/360017341694-Managing-API-keys#idm45892557001984).
3. In Firefly, click **Settings > Integrations**.
4. Click **Add New > NS1**.
5. Enter a descriptive name in the Nickname field.
6. Copy and paste your API key into the API Key field.
7. Click **Next**.
8. Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your NS1 DNS records list will stay updated automatically.
* You can enforce IaC or policies on your NS1 assets.
* Supports monitoring of NS1 DNS records and zones.


# PagerDuty

Firefly integrates with PagerDuty to pull in information about your incidents, services, and on-call schedules as "assets". This means in your Firefly Inventory, you'll see PagerDuty services and incidents listed (with their configurations) just like cloud assets. You can then enforce IaC or policies on them as well (for example, ensuring all services follow a naming convention or have proper escalation policies).

## Prerequisites

* A PagerDuty account with administrative access.
* A Read-Only API Access Key.
* (Optional) A User Token REST API Key for enhanced functionality.
* Access to PagerDuty API endpoints.
* Ability to generate API keys.

## Setup Procedure

1. Log in to your PagerDuty account.
2. Create a Read-Only API Access Key:
   * Navigate to [PagerDuty API Access Keys](https://support.pagerduty.com/docs/api-access-keys#section-generating-a-general-access-rest-api-key).
   * Generate a new Read-Only API Access Key.
   * Copy the key for use in Firefly.
3. (Optional) Generate a User Token REST API Key:
   * Navigate to [PagerDuty User Token REST API Keys](https://support.pagerduty.com/docs/api-access-keys#section-generate-a-user-token-rest-api-key).
   * Generate a new User Token.
   * Copy the token for use in Firefly.
4. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > PagerDuty**.
   * Enter a descriptive name in the Nickname field.
   * Paste your Read-Only API Access Key into the API Access Key field.
   * (Optional) Paste your User Token into the User Token field.
   * Click **Next**.
   * Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your PagerDuty services and incidents list will stay updated automatically.
* You can enforce IaC or policies on your PagerDuty assets.
* The integration supports both Read-Only API Access Keys and User Token REST API Keys for enhanced functionality.
* Supports monitoring of PagerDuty services, incidents, on-call schedules, and escalation policies.


# MongoDB Atlas

MongoDB Atlas integration allows you to connect your MongoDB Atlas clusters to Firefly. This integration enables Firefly to discover and track your MongoDB Atlas assets, including clusters, databases, and configuration details. This integration is particularly useful for tracking database-as-a-service (DBaaS) assets alongside your other infrastructure components.

## Prerequisites

* MongoDB Atlas account with administrative access.
* Ability to create API keys with Organization Read Only permissions.
* Access to MongoDB Atlas API endpoints.
* Required credentials:
  * API Public Key.
  * API Private Key.
  * Project ID.

## Setup Procedure

1. Log in to your MongoDB Atlas account at <https://cloud.mongodb.com/>.
2. From the left menu, select **Access Manager**.
3. Select your Organization.
4. From the top menu, select **API Keys > Create API Key**.
5. Enter a descriptive name for your API key.
6. In Organization Permissions, select **Organization Read Only** and click **Next**.
7. Copy both the Public Key and Private Key.
8. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > MongoDB Atlas**.
   * Enter a descriptive name in the Nickname field.
   * Paste your Public Key and Private Key.
   * Click **Next**.
   * Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your MongoDB Atlas configurations list will stay updated automatically.
* You can enforce IaC or policies on your MongoDB Atlas assets.
* Supports monitoring of MongoDB Atlas clusters, databases, and configuration details.


# HashiCorp Vault

Firefly can integrate with HashiCorp Vault to track secrets engines and configurations. This integration allows you to ensure your Vault setup follows infrastructure as code principles. The integration focuses on tracking Vault's configuration and setup, not the secrets themselves, aligning with infrastructure as code principles while maintaining security best practices.

## Prerequisites

* HashiCorp Vault server with administrative access.
* Vault server address.
* A token with appropriate policies to read mounts and configurations.
* Access to create and manage policies.
* Ability to configure authentication methods.

## Setup Procedure

### 1. Create Required Policy

1. Log in to your HashiCorp Vault account.
2. Navigate to **Policies**.
3. Create a new policy with the following permissions:

```hcl
path "*"
{
  capabilities = ["read","list"]
}

path "auth/token/renew-self"
{
  capabilities = ["update"]
}

path "auth/token/create"
{
  capabilities = ["update", "create"]
}
```

### 2. Configure Authentication

1. Navigate to **Access**.
2. Enable a new auth method of type `userpass`.
3. Create a new user.
4. Attach the previously created policy to the user.

### 3. In Firefly

1. Go to **Settings > Integrations**.
2. Click **Add New > HashiCorp Vault**.
3. Enter a descriptive name in the Nickname field.
4. Enter the Vault endpoint address.
5. Enter the username and password for the user you created in step 2.
6. Click **Next**.
7. Click **Done**.

## Configuration Details

* Firefly scans every 8 hours by default for SaaS data.
* Your HashiCorp Vault configurations list will stay updated automatically.
* You can enforce IaC or policies on your HashiCorp Vault assets.
* Supports monitoring of HashiCorp Vault secrets engines, authentication methods, mount points, and policy configurations.

> **Note:** This integration focuses on tracking Vault's configuration and setup, not the secrets themselves. This approach aligns with infrastructure as code principles while maintaining security best practices.


# Integrating IaC Remote State

Firefly supports integrating with various Infrastructure as Code (IaC) remote state providers to help you manage and govern your infrastructure state files. These integrations allow you to track and manage your infrastructure state across different platforms and providers.

> **Note:** After adding a remote state integration, it may take a few minutes for Firefly to initially fetch your state files. State files are automatically refreshed periodically to ensure your infrastructure state remains up-to-date.

## Supported Remote State Providers

### Cloud Provider Storage

* [Google Cloud Storage](/integrations/iac-remote-state/google-cloud-storage)

### State Management Platforms

* [Terraform Cloud](/integrations/iac-remote-state/terraform-cloud)
* [env0](/integrations/iac-remote-state/env0)

### Service Discovery & State Management

* [HashiCorp Consul](/integrations/iac-remote-state/hashicorp-consul)

### Self-hosted State Redaction

> Use the Firefly States Redactor to securely fetch, scan, and redact sensitive data from Terraform state files before mirroring them to S3. This self-hosted solution is ideal for organizations that require on-premises or cloud-native control over state file security and compliance.

* [Firefly States Redactor](/integrations/iac-remote-state/states-redactor)

## Request Additional Remote State Support

If you need integration with a remote state provider that is not currently supported, please contact Firefly's support team via email at <help@firefly.ai>. When requesting a new remote state integration, please provide details about the platform and your specific use case to help our team better understand your requirements.


# Terraform Cloud

Firefly integrates with Terraform Cloud and Terraform Enterprise to pull in workspaces tfstate files. This integration allows Firefly to analyze your Terraform state files, providing comprehensive visibility into your infrastructure resources managed through Terraform Cloud or Enterprise.

## Prerequisites

* A Terraform Cloud or Terraform Enterprise account.
* An API token with read permissions on the organization.

## Integrate Terraform Cloud

This procedure allows Firefly to access your Terraform Cloud IaC stacks.

### Setup Procedure

1. Log in to your Terraform Cloud account.
2. Create an API token.
3. Copy the token.
4. In Firefly, click **Settings > Integrations**.
5. Click **Add New > Terraform Cloud**.
6. Enter a descriptive name into the **Nickname** field.
7. Paste the token into the **API token** field.
8. Click **Next**.
9. Click **Done**.

## Integrate Terraform Enterprise

This procedure allows Firefly to access your Terraform Enterprise IaC stacks.

Terraform Enterprise is a self-hosted version of Terraform Cloud used either on-premises or in your public cloud.

### Setup Procedure

1. Log in to your Terraform Enterprise account.
2. Create an API token.
3. Copy the token.
4. In Firefly, click **Settings > Integrations**.
5. Click **Add New > Terraform Cloud**.
6. Enter a descriptive name into the **Nickname** field.
7. Paste the token into the **API token** field.
8. Enter the domain name of your Terraform Enterprise environment in the **Terraform Enterprise** field.
9. Allow external access to the following IPs:
   * 3.224.145.192
   * 54.83.245.177
   * 3.213.167.195
   * 54.146.252.237
   * 34.226.97.113
   * 54.166.221.160
   * 52.22.128.83
   * 52.86.171.233
   * 34.200.154.87
   * 100.25.162.125
   * 18.209.82.232
   * 98.83.246.85
   * 54.144.58.153
10. Click **Next**.
11. Click **Done**.

## Configuration Details

* Firefly scans your workspaces tfstate files by default every 4 hours.
* Your Terraform Cloud workspaces state files list will stay updated automatically.


# Google Cloud Storage

Firefly integrates with Google Cloud Storage to pull in Terraform state files. This integration allows Firefly to analyze your Terraform state files stored in Google Cloud Storage buckets, providing comprehensive visibility into your infrastructure resources managed through Terraform.

## Prerequisites

* A Google Cloud Platform account.
* A service account with appropriate permissions to access the storage buckets containing Terraform state files.

## Integrating a new account

1. Log into your Google Cloud service account, and click **Create Service Account**.
2. Add the Service account details, and click **Create and Continue**.
3. Add the following role:
   * `storage.objectViewer` conditional to tfstate suffix.
4. Click **Save > Done**.
5. Click the kebab menu.
6. Click **Manage keys > Add Key > Create new key**.
7. To download a service account key file, click **JSON > Create**.
8. In Firefly, click **Settings > Integrations**.
9. Click **Add New > Google Cloud Storage**.
10. Enter a **Nickname** and **Project ID**.
11. Paste or upload the account key file into the **Service Account Key** field.
12. Click **Next**.
13. Click **Done**.

## Integrating an existing account

1. Log in to your Google Cloud service account.
2. Add the following roles to the account you want to integrate:
   * `storage.objectViewer` conditional to tfstate suffix.
3. Click the kebab menu.
4. Click **Manage keys > Add Key > Create new key**.
5. To download a service account key file, click **JSON > Create**.
6. In Firefly, click **Settings > Integrations**.
7. Click **Add New > Google Cloud Storage**.
8. Enter a **Nickname** and **Project ID**.
9. Paste or upload the account key file into the **Service Account Key** field.
10. Click **Next**.
11. Click **Done**.

## Configuration Details

* Firefly scans your Google Cloud Storage buckets by default every 4 hours.
* Your Google Cloud Storage buckets state files list will stay updated automatically.


# env0

Firefly integrates with env0 to pull in Terraform and OpenTofu state files. This integration allows Firefly to analyze your Terraform and OpenTofu state files, providing comprehensive visibility into your infrastructure resources managed through env0.

## Prerequisites

* An env0 account.
* An API key with read permissions on the organization.

## Setup Procedure

1. Log in to your env0 account.
2. Create an API key.
3. Copy the API key, API key secret, and API key token.
4. In Firefly, click **Settings > Integrations**.
5. Click **Add New > env0**.
6. Enter a descriptive name into the **Nickname** field.
7. Paste the API key into the **API key ID** field.
8. Paste the API key secret into the **API key secret** field.
9. Paste the API key token into the **API key token** field.
10. Click **Next**.
11. Click **Done**.

## Configuration Details

* Firefly scans your env0 state files by default every 4 hours.
* Your env0 state files list will stay updated automatically.


# HashiCorp Consul

Firefly integrates with HashiCorp Consul to pull in key-value pairs from Consul. This integration allows Firefly to analyze your Consul key-value pairs, providing comprehensive visibility into your infrastructure resources managed through Consul.

## Prerequisites

* A HashiCorp Consul cluster.
* A token with read permissions on the Consul cluster.

## Network Requirements

If your Consul is deployed on-prem, allow the following IP addresses to connect to the cluster:

* 3.224.145.192
* 54.83.245.177
* 3.213.167.195
* 54.146.252.237
* 34.226.97.113
* 54.166.221.160
* 52.22.128.83
* 52.86.171.233
* 34.200.154.87
* 100.25.162.125
* 18.209.82.232
* 98.83.246.85
* 54.144.58.153

## Setup Procedure

1. In Firefly, click **Settings > Integrations**.
2. Click **Add New > HashiCorp Consul**.
3. Go to [HCP](https://portal.cloud.hashicorp.com/) (for HCP Consul), or your on-prem Consul UI (for self-hosted Consul), to create a Consul access token.
4. Copy the token.
5. In Firefly, enter a descriptive name into the **Nickname** field.
6. Enter the **Public cluster address** of your Consul cluster.
7. Paste the Consul access token into the **Token** field.
8. Click **Next**.
9. Click **Done**.

## Configuration Details

* Firefly scans your Consul key-value store by default every 4 hours.
* Your Consul key-value pairs state files list will stay updated automatically.


# Firefly States Redactor

The Firefly states redactor is a self-hosted solution for securely handling Terraform state files. It fetches state files from remote sources, scans for sensitive data, and redacts secrets before mirroring the files to an S3 bucket. This helps organizations ensure that sensitive information is not exposed in their infrastructure state management workflows.

## Features

* Fetches Terraform state files from supported remote sources (e.g., S3, Terraform Cloud, ArgoCD).
* Identifies and redacts sensitive data within state files.
* Mirrors redacted state files to a designated S3 bucket.
* Integrates with [Gitleaks](https://github.com/zricethezav/gitleaks) to further scan for secrets.
* Can be deployed as a Kubernetes CronJob or as an ECS Fargate task.

## Architecture

The redactor is deployed as a Kubernetes CronJob or ECS Fargate task that runs every 2 hours by default. It is designed for EKS clusters and uses IAM roles for access to S3. The redactor can also be run on ECS Fargate for organizations preferring AWS-native orchestration.

![Firefly States Redactor Architecture](https://user-images.githubusercontent.com/31516429/205700568-3197fb4e-84ff-45a1-8693-fc82685bba85.png)

## Prerequisites

* An EKS cluster (for Kubernetes deployment) or an ECS cluster (for AWS Fargate deployment).
* An S3 bucket for storing redacted state files.
* IAM role with the following permissions:
  * `s3:GetBucket`, `s3:ListBucket`, `s3:GetObject`, `s3:PutObject`.
  * (Optional) `kms:Decrypt` if the bucket is encrypted.
* Credentials for the remote state provider (e.g., Terraform Cloud token, ArgoCD token).

## Installation (Kubernetes Helm)

To install the states redactor using Helm:

```bash
helm repo add firefly-redactor https://gofireflyio.github.io/states-redactor
helm install states-redactor firefly-redactor/firefly-redactor -f values.yaml --namespace=firefly --create-namespace
```

## Configuration Examples (`values.yaml`)

### Terraform Cloud

```yaml
serviceAccount:
  annotations: {
     "gofirefly.io/component": firefly-redactor,
     "eks.amazonaws.com/role-arn": aws:aws:iam::123456789:role/my-role
  }
firefly:
  accountId: GIVEN-BY-FIREFLY
  crawlerId: GIVEN-BY-FIREFLY
  location:
    tfc:
      organization: example
      address: example-tfc-enteprise.com
  type: tfc

credentials:
  tfcToken: MY-ORGANIZATION-TOKEN
  tfcCustomDomain: https://example-tfc-enteprise.com

redactorMirrorBucketName: my-mirror-bucket
redactorMirrorBucketRegion: us-east-1
logging:
  remoteHash: GIVEN-BY-FIREFLY
```

### S3 Bucket

```yaml
serviceAccount:
  annotations: {
     "gofirefly.io/component": firefly-redactor,
     "eks.amazonaws.com/role-arn": aws:aws:iam::123456789:role/my-role
  }
firefly:
  accountId: GIVEN-BY-FIREFLY
  crawlerId: GIVEN-BY-FIREFLY
  location:
    s3:
     isLocal: true
     bucket: my-bucket
     region: us-east-1
  type: s3

redactorMirrorBucketName: my-mirror-bucket
redactorMirrorBucketRegion: us-east-1
logging:
  remoteHash: GIVEN-BY-FIREFLY
```

## Running on ECS (Terraform Module)

You can also run the states redactor on ECS Fargate using the provided Terraform module:

```hcl
module "states-redactor-ecs" {
  source = "github.com/gofireflyio/states-redactor//terraform/ecs"
  aws_region = "us-west-2"

  firefly_account_id = "<ACCOUNT_ID>"             // Given by Firefly
  firefly_crawler_id = "<CRAWLER_ID>"             // Given by Firefly
  firefly_remote_log_hash = "<REMOTE_LOG_HASH>"   // Given by Firefly

  redacted_bucket_name = "tfstate-target-bucket"
  source_bucket_name = "tfstate-source-bucket"
  source_bucket_region = "us-west-2"

  container_cpu = 256
  container_memory = 512
  schedule_expression = "rate(2 hours)"

  security_groups = ["sg-1234"]
  subnets = ["subnet-1234", "subnet-5678"]
  assign_public_ip = false // If false, add VPC endpoints to reach the ECR
  ecs_cluster_arn = "arn:aws:ecs:us-west-2:0123456789:cluster/firefly-states-redactor" // If empty, will create a cluster
}
```

## References

* [states-redactor GitHub repository](https://github.com/gofireflyio/states-redactor)
* [Gitleaks](https://github.com/zricethezav/gitleaks)

## Need Help?

Reach out to your Firefly Customer Success manager or email <help@firefly.ai> for assistance with your states redactor configuration.


# Integrating Version Control

Firefly supports integrating with various version control systems to help manage and track your code assets, repositories, and related configurations.

> **Note:** After adding a version control integration, it may take a few minutes for Firefly to initially fetch your repositories and related assets. All assets are automatically refreshed every few hours to ensure your data in Firefly remains up-to-date.

## Supported Version Control Systems

* [GitHub](/integrations/version-control/github)
* [GitLab](/integrations/version-control/gitlab)
* [Bitbucket](/integrations/version-control/bitbucket)
* [Azure DevOps](/integrations/version-control/azuredevops)

## Request Additional Version Control Support

If you need integration with a version control system that is not currently supported, please contact Firefly's support team via email at <help@firefly.ai>. When requesting a new version control integration, please provide details about the platform and your specific use case to help our team better understand your requirements.


# GitHub

Firefly integrates with GitHub to connect your infrastructure code repositories with your cloud resources. This integration enables powerful features like tracing cloud resources back to their defining code ("Jump to Code") and automatically creating Pull Requests for newly codified resources and drift remediation.

## Prerequisites

* A GitHub account with access to your infrastructure repositories.
* Appropriate permissions to install GitHub Apps or create Personal Access Tokens.
* Repositories containing Terraform or other IaC files you want to connect to Firefly.

## Setup Procedure

1. In Firefly, click **Settings > Integrations**.
2. Click **Add New > GitHub** (under version control integrations).
3. Install the Firefly GitHub application.
4. Select your Terraform repositories or **All repositories**.
5. Click **Install & Authorize**.
6. Enter your Password and click **Confirm password**.
7. Click **Continue with GitHub**.
8. Click **Authorize Infralight**.

## GitHub Enterprise Server (via AWS PrivateLink)

If you run **GitHub Enterprise Server** (GHES) inside a private VPC that isn't reachable over the public internet, Firefly can connect to it over AWS PrivateLink — keeping all traffic between Firefly and your GHES instance on the AWS backbone, with no public exposure.

1. Set up PrivateLink connectivity between your GHES VPC and Firefly. See the [AWS PrivateLink integration guide](/integrations/aws-privatelink) for prerequisites and customer-side setup (NLB + VPC Endpoint Service).
2. Coordinate with your Firefly contact to configure the GHES integration against your private endpoint.

## Features Enabled

* **Jump to Code**: Trace resources in your cloud inventory back to the GitHub file and specific line that defines them.
* **Automated Pull Requests**: When Firefly codifies an unmanaged resource, it can commit the new Terraform code as a Pull Request.
* **IaC Tracking**: Firefly maintains awareness of which resources are defined in code and which are not.
* **Drift Remediation**: Firefly can detect drift between the code and the actual resources and create a Pull Request to fix it.


# GitLab

Firefly integrates with GitLab to connect your infrastructure code repositories with your cloud resources. This integration enables powerful features like tracing cloud resources back to their defining code ("Jump to Code") and automatically creating Merge Requests for newly codified resources and drift remediation.

## Prerequisites

* A GitLab account with access to your infrastructure repositories.
* Appropriate permissions to create OAuth applications.
* Repositories containing Terraform, CloudFormation, or other IaC files you want to connect to Firefly.

## Setup Procedure

1. Log in to your GitLab account.
2. Click on your Avatar icon on the top right panel, then click on **Preferences**.
3. Select **Applications**, and then click on **Add new application**.
4. Select a name for the application.
5. In the **Redirect URI**, please paste the following URL: `https://app.firefly.ai/integrations/gitlab-integration`
6. In the **scope** section, please select the **API** option.

   > **Note**: API must be selected for the integration to be successful.
7. Scroll to the bottom of the page and click **Save application**. You will be directed to a new screen where you can see the Application ID, Secret and Callback URL.
8. Please copy the **Application ID** and paste it in Firefly's GitLab Integration page.
9. Please copy the **Secret** and paste it in Firefly's GitLab Integration page.
10. After filling the information, click the **Authorize** button in Firefly's GitLab Integration page.
11. In the new page that you were directed to, press the **Authorize \<APPLICATION NAME>** button.

    > **Note**: You must authorize the application for the integration to be successful.
12. After authorizing the new application, you will be redirected back to Firefly's application.
13. After the integration is completed, please select the **Project IDs** and/or **Group IDs** for webhooks to be installed from the dropdown menu below the "Authorize" button.

## Features Enabled

* **Jump to Code**: Trace resources in your cloud inventory back to the GitLab file and specific line that defines them.
* **Automated Merge Requests**: When Firefly codifies an unmanaged resource, it can commit the new infrastructure code as a Merge Request.
* **IaC Tracking**: Firefly maintains awareness of which resources are defined in code and which are not.
* **Drift Remediation**: Firefly can detect drift between the code and the actual resources and create a Merge Request to fix it.
* **Workspace Integration**: GitLab can be selected during Workspace creation or modification, enabling seamless integration with associated GitLab repositories.


# Azure DevOps

Firefly integrates with Azure DevOps to connect your infrastructure code repositories with your cloud resources. This integration enables powerful features like tracing cloud resources back to their defining code ("Jump to Code") and automatically creating Pull Requests for newly codified resources and drift remediation.

## Prerequisites

To successfully integrate Firefly with your Azure DevOps account, you must be the workspace admin or have these necessary permissions:

* Edit subscriptions
* View subscriptions
* Manage repositories
* Edit policies
* Contribute to pull requests
* Read repositories
* Write to repositories

## Setup Procedure

1. Enter a descriptive name in the **Nickname** field below.
2. Click **Authorize with Microsoft** to authenticate with your Azure DevOps account.
3. Sign in with your Microsoft account and grant the required permissions.
4. After authorization, you will be redirected back to this page.
5. Click **Next** to install webhooks and complete the integration.

## Features Enabled

* **Jump to Code**: Trace resources in your cloud inventory back to the Azure DevOps file and specific line that defines them.
* **Automated Pull Requests**: When Firefly codifies an unmanaged resource, it can commit the new infrastructure code as a Pull Request.
* **IaC Tracking**: Firefly maintains awareness of which resources are defined in code and which are not.
* **Drift Remediation**: Firefly can detect drift between the code and the actual resources and create a Pull Request to fix it.

## Scan Custom Branches for Modules

By default, Firefly scans modules from your repositories' default branches. You can configure custom branches to scan on a per-repo basis, allowing Firefly to discover modules from feature branches, release branches, or any other branch in your Azure DevOps repositories.

> **Note:** The main branch is not automatically scanned when custom branches are configured—select it explicitly if needed.

### Configuring Custom Branch Scanning

1. Navigate to **Settings > Integrations** and locate your Azure DevOps integration.
2. Click **Edit Integration**.
3. Scroll to the **Scan custom branches for modules** section at the bottom of the modal.
4. In the first row, select a **Repository** from the dropdown (lists all available repos from the integration).
5. Once a repository is selected, the **Branch** dropdown becomes available—select the branch to scan.
6. To add additional repo-branch pairs, click **+ Add New** below the existing rows.
7. Click **Save** to apply your configuration.

Firefly scans the HEAD of each selected branch for modules. Discovered modules appear in the **IaC Explorer > Modules** tab.

### Rules and Limitations

* Each row represents an independent repository-branch pair.
* The **Branch** dropdown is disabled until a repository is selected.
* A maximum of **10** repo-branch pairs can be configured per integration.
* Each row can be removed individually using the delete icon.


# CodeCommit

Firefly integrates with AWS CodeCommit to connect your infrastructure code repositories with your cloud resources. This integration enables powerful features like tracing cloud resources back to their defining code ("Jump to Code") and automatically creating Pull Requests for newly codified resources and drift remediation.

## Prerequisites

* An AWS account with access to your infrastructure repositories in CodeCommit.
* Appropriate permissions to create IAM roles and CloudFormation stacks.
* Repositories containing Terraform, CloudFormation, or other IaC files you want to connect to Firefly.

## Setup Procedure

1. Log in to your AWS account with permission to create CloudFormation and IAM AWS resources.
2. Copy your AWS account ID (located at the top right corner of the AWS console) to the clipboard.
3. In Firefly, click **Settings > Integrations**.
4. Click **Add New > AWS CodeCommit**.
5. Enter a descriptive name in the **Nickname** field.
6. Paste the AWS account ID.
7. Click **Launch Stack**.
8. Click **Done**.

## Features Enabled

* **Jump to Code**: Trace resources in your cloud inventory back to the CodeCommit file and specific line that defines them.
* **Automated Pull Requests**: When Firefly codifies an unmanaged resource, it can commit the new infrastructure code as a Pull Request.
* **IaC Tracking**: Firefly maintains awareness of which resources are defined in code and which are not.
* **Drift Remediation**: Firefly can detect drift between the code and the actual resources and create a Pull Request to fix it.


# Bitbucket

Firefly integrates with Bitbucket to connect your infrastructure code repositories with your cloud resources. This integration enables powerful features like tracing cloud resources back to their defining code ("Jump to Code") and automatically creating Pull Requests for newly codified resources and drift remediation.

## Prerequisites

* A Bitbucket account with access to your infrastructure repositories.
* Appropriate permissions to create an OAuth consumer or an Atlassian API token (depending on the authentication method you choose).
* Repositories containing Terraform, CloudFormation, or other IaC files you want to connect to Firefly.

## Setup Procedures

Firefly supports two authentication methods for Bitbucket Cloud. Choose the one that best fits your needs:

* [**OAuth**](#oauth) — authorize Firefly through a Bitbucket OAuth consumer.
* [**API Token**](#api-token) — authenticate with a scoped Atlassian API token.

### OAuth

> **Prerequisite:** To successfully integrate Firefly with your Bitbucket account, you must be the workspace admin.

1. Log in to your Bitbucket account.
2. Click on your Avatar on the top right panel, then click on **All workspaces**.
3. Select the workspace Firefly will be integrated with.
4. Click on the Settings icon on the top right panel (to the left of your Avatar) and select **Workspace settings**.
5. Please scroll down in the left panel and click on **OAuth clients**.
6. Click on **Create OAuth client** to create a new integration with Firefly.

   * Select a name for the application.
   * Add a description (optional).
   * In the **Callback URL**, please paste the following URL: `https://app.firefly.ai/integrations/bitbucket-integration`
   * In the **Permission** section, please select the following:
     * Account: read

     * Repositories: write and admin

     * Pull requests: write

     * Webhooks: read and write

   > **Note:** All the permissions must be selected for the integration to be successful.
7. Scroll to the bottom of the page and click **Save**. You will be directed to the OAuth clients where you can see the newly created client.
8. Click on the new client to see its details:
   * Please copy the **Client ID** and paste it in Firefly's Bitbucket Integration page in the **Client ID** field.
   * Please copy the **Secret** and paste it in Firefly's Bitbucket Integration page in the **Secret** field.
9. After filling in the information, please click the **Authorize** button in Firefly's Bitbucket Integration page.
10. In the new page that opens, please press **Grant Access**.

    > **Note:** You must authorize for the integration to be successful.
11. After authorizing the new application, you will be redirected back to Firefly's application.
12. After the integration is completed, please enter your Bitbucket account email in the **Bitbucket Email** field and the workspace ID in the **Workspace ID** field. Click **Create Integration** to check if the workspace exists.
13. When the validation is complete, click on the **Next** button for webhooks to be installed.

### API Token

> **Prerequisite:** Create a scoped Atlassian API token (not an app password). Bitbucket Cloud app passwords are being retired. Follow [Create an API token](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/).

1. Select your profile in the upper-right corner of Bitbucket, then open **Account settings**.
2. On the Atlassian Account page, open the **Security** tab.
3. Select **Create and manage API tokens**, then **Create API token with scopes**.
4. Give the token a name and an expiry date, then select **Next**.
5. Select **Bitbucket** as the app, then select **Next**.
6. Select the following scopes (see API token permissions), then select **Next**:

   * **Account: read**
     * `read:account`
     * `read:workspace:bitbucket`
   * **Repositories: write and admin**
     * `read:repository:bitbucket`
     * `write:repository:bitbucket`
     * `admin:repository:bitbucket`
   * **Pull requests: write**
     * `read:pullrequest:bitbucket`
     * `write:pullrequest:bitbucket`
   * **Webhooks: read and write**
     * `read:webhook:bitbucket`

     * `write:webhook:bitbucket`

   > **Note:** In the granular token model, `write` does not imply `read` — select the `read:*` scopes explicitly. An unscoped API token will fail with `401`.
7. Review and select **Create token**. Copy the token immediately — it is shown only once.
8. In Firefly, enter your Atlassian account email, paste the API token, and enter the **Workspace ID**. Click **Create Integration**.
9. When validation completes, click **Next** for webhooks to be installed.

### Integrate Bitbucket Data Center

1. Enter the domain for your Bitbucket Data Center instance and paste the app password into the **App Password** box.

## Features Enabled

* **Jump to Code**: Trace resources in your cloud inventory back to the Bitbucket file and specific line that defines them.
* **Automated Pull Requests**: When Firefly codifies an unmanaged resource, it can commit the new infrastructure code as a Pull Request.
* **IaC Tracking**: Firefly maintains awareness of which resources are defined in code and which are not.
* **Drift Remediation**: Firefly can detect drift between the code and the actual resources and create a Pull Request to fix it.


# Integrating Notifications

Firefly supports a variety of notification integrations to help you stay informed about important events, alerts, and changes in your infrastructure. These integrations enable real-time communication and ensure that the right team members are notified about critical updates.

## Supported Notification Channels

### Messaging Platforms

* [Slack](/integrations/notifications/slack)
* [Microsoft Teams](/integrations/notifications/microsoft-teams)
* [Google Chat](/integrations/notifications/google-chat)
* [Webex](/integrations/notifications/webex)

### Incident Management

* [PagerDuty](/integrations/notifications/pagerduty)
* [Opsgenie](/integrations/notifications/opsgenie)
* [Torq](/integrations/notifications/torq)

### Custom Integrations

* [Webhook](/integrations/notifications/webhook)

## Request Additional Notification Support

If you need integration with a notification platform that is not currently supported, please contact Firefly's support team via email at <help@firefly.ai>. When requesting a new notification integration, please provide details about the platform and your specific use case to help our team better understand your requirements.


# Slack

Firefly integrates with Slack to provide rich notifications for various events and alerts. This integration enables teams to receive real-time updates about infrastructure changes, policy violations, drift detection, and other important events directly in their Slack channels.

When integrating an Slack, you have two primary methods:

* [Slack App](#slack-app).
* [Slack Webhook](#slack-webhook).

## Prerequisites

* A Slack workspace with administrative access.
* Appropriate permissions to install apps or create webhooks.
* Channels where you want to receive Firefly notifications.

## Setup Procedure

### Slack App (Recommended Method)

1. In Firefly, click **Settings > Integrations**.
2. Click **Add New > Slack** (under messaging integrations).
3. Select **Slack App** from the Integration type field.
4. Click to install the Firefly Slack application.
5. Authorize the app in your workspace.
6. Select the desired channel for notifications.
7. Click **Next**.
8. Click **Done**.

### Slack Webhook (Legacy Method)

> **Note**: This integration is deprecated. We recommend using the Slack App integration.

1. Generate a webhook URL for your Slack channel:
   * Visit the [Incoming Webhooks](https://gofireflyio.slack.com/apps/A0F7XDUAZ-incoming-webhooks?tab=more_info) page.
   * Click **Add to Slack**.
   * Choose a channel.
   * Click **Add Incoming Webhooks integration**.
   * Copy the Webhook URL.
2. In Firefly, click **Settings > Integrations**.
3. Click **Add New > Slack**.
4. Select **Slack Webhook** from the Integration type field.
5. Enter a descriptive name in the **Nickname** field.
6. Paste the webhook URL.
7. Click **Next**.
8. Click **Done**.

## Features Enabled

* **Real-time Notifications**: Receive immediate alerts for important events.
* **Rich Message Formatting**: Detailed, formatted messages with direct links to Firefly.
* **Customizable Alerts**: Configure which events trigger notifications.
* **Channel-specific Routing**: Send different types of alerts to different channels.
* **Interactive Messages**: Click through to Firefly directly from Slack notifications.

> **Note:** In the integration settings page, use the notifcation test button to test the integration.


# Microsoft Teams

Firefly integrates with Microsoft Teams to provide rich notifications for various events and alerts. This integration enables teams to receive real-time updates about infrastructure changes, policy violations, drift detection, and other important events directly in their Teams channels.

> ⚠️ **Microsoft has deprecated legacy Office 365 Connector webhooks** (completed May 2025). If you are using an old `*.office.com` webhook URL, you must migrate to the new **Teams Workflows (Power Automate)** webhook to continue receiving notifications. See [Microsoft's migration guide](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook) for details.

## Prerequisites

* A Microsoft Teams workspace with administrative access
* Appropriate permissions to create webhooks
* Channels where you want to receive Firefly notifications

## Setup Procedure

1. In Microsoft Teams, go to the channel → **Manage channel** → **Workflows** → create a new **"Post to a channel when a webhook request is received"** workflow.
2. Copy the new webhook URL generated by the workflow.
3. In Firefly, click **Settings > Integrations**.
4. Click **Add New > Teams**.
5. Enter a descriptive name in the **Nickname** field.
6. Paste the Webhook URL.

   > ⚠️ **Important:** Check that your URL does **not** contain `:443` after `.com`. Some versions of the Microsoft Teams UI generate URLs with `:443` appended, which will cause the integration to fail. Remove it if present.
   >
   > ✅ Correct: `https://...powerplatform.com/powerautomate/...` ❌ Incorrect: `https://...powerplatform.com:443/powerautomate/...`
7. Click **Next**.
8. Click **Done**.

## Features Enabled

* **Real-time Notifications**: Receive immediate alerts for important events.
* **Rich Message Cards**: Detailed, formatted messages with direct links to Firefly.
* **Customizable Alerts**: Configure which events trigger notifications.
* **Channel-specific Routing**: Send different types of alerts to different channels.
* **Interactive Messages**: Click through to Firefly directly from Teams notifications.

> **Note:** In the integration settings page, use the notification test button to test the integration.


# PagerDuty

Firefly integrates with PagerDuty to provide real-time notifications for critical infrastructure events, policy violations, and other important alerts. This integration enables teams to receive immediate notifications and manage incidents effectively through PagerDuty's incident management platform.

When integrating with PagerDuty, you have two primary methods:

* [Integration Key](#integration-key).
* [General Access REST API Key](#general-access-rest-api-key).

## Prerequisites

* A PagerDuty account with administrative access.
* Appropriate permissions to generate integration keys or API keys.
* A configured PagerDuty service for receiving notifications.

## Setup Procedure

### Integration Key (Recommended Method)

Use this method for optimal integration with a specific PagerDuty service.

1. Generate an Integration Key:
   * Visit the [PagerDuty documentation](https://support.pagerduty.com/docs/services-and-integrations#generate-a-new-integration-key).
   * Follow the instructions to generate a new integration key.
   * Copy the Integration Key.
2. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > PagerDuty**.
   * Enter a descriptive name in the **Nickname** field.
   * Select **Integration Key** from the Integration Type field.
   * Paste the Integration Key in the **Key** box.
   * Click **Next**.
   * Click **Done**.

### General Access REST API Key

Use this method to generate notifications for all services available in your PagerDuty account.

> **Note**: For optimal integration, we recommend using an Integration Key instead.

1. Generate a Read-Only REST API Key:
   * Visit the [PagerDuty documentation](https://support.pagerduty.com/docs/api-access-keys#generate-a-general-access-rest-api-key).
   * Follow the instructions to generate a general access REST API key.
   * Copy the API key.
2. In Firefly:
   * Click **Settings > Integrations**.
   * Click **Add New > PagerDuty**.
   * Enter a descriptive name in the **Nickname** field.
   * Select **General Access REST API Key** from the Integration Type field.
   * Paste the API key in the **Key** field.
   * Click **Next**.
   * Click **Done**.

## Features Enabled

* **Real-time Incident Creation**: Automatically create PagerDuty incidents for critical events.
* **Service-specific Routing**: Direct notifications to specific PagerDuty services.
* **Rich Incident Details**: Include comprehensive information in incident descriptions.
* **Automated Resolution**: Close incidents when issues are resolved in Firefly.
* **Priority Management**: Set appropriate incident priorities based on event severity.

> **Note:** In the integration settings page, use the notifcation test button to test the integration.


# Opsgenie

Firefly integrates with Opsgenie to provide robust alerting and incident management capabilities. This integration enables teams to receive and manage infrastructure alerts, policy violations, and other critical events through Opsgenie's powerful incident management platform.

## Prerequisites

* An Opsgenie account with administrative access.
* Appropriate permissions to create API integrations.
* Access to Firefly's integration settings.

## Setup Procedure

1. Generate an API key for Opsgenie:
   * Visit the [Opsgenie API Integration](https://support.atlassian.com/opsgenie/docs/create-a-default-api-integration/) documentation.
   * Follow the steps to create a default API integration.
   * Copy the generated API key.
2. In Firefly, click **Settings > Integrations**.
3. Click **Add New > Opsgenie**.
4. Enter a descriptive name in the **Nickname** field.
5. Paste the API key in the **API key** field.
6. (Optional) Create a new label for better organization.
7. Click **Next**.
8. Click **Done**.

## Features Enabled

* **Alert Management**: Centralized handling of infrastructure alerts.
* **Incident Response**: Streamlined incident management workflow.
* **Team Notifications**: Alert routing to appropriate teams.
* **Priority Management**: Critical alert prioritization.
* **Integration with Opsgenie's Features**: Leverage Opsgenie's full incident management capabilities.

> **Note:** In the integration settings page, use the notifcation test button to test the integration.


# Torq

Firefly integrates with Torq to provide automated workflows and notifications for various events and alerts. This integration enables teams to receive real-time updates about infrastructure changes, policy violations, drift detection, and other important events through Torq's automation platform.

## Prerequisites

* A Torq account with administrative access.
* Appropriate permissions to create integrations and webhooks.
* Access to Firefly's integration settings.

## Setup Procedure

1. Log in to your Torq account
2. Click **Integrations > Triggers > Firefly**.
3. Click **Add**.
4. Enter a descriptive name in the **Integration Name** field and select **Add**.
5. Copy the webhook URL.
6. In Firefly, click **Settings > Integrations**.
7. Click **Add New > Torq**.
8. Enter a descriptive name in the **Nickname** field.
9. Paste the webhook URL.
10. Click **Next**.
11. Click **Done**.

## Features Enabled

* **Automated Workflows**: Trigger Torq workflows based on Firefly events.
* **Real-time Notifications**: Receive immediate alerts for important events.
* **Customizable Alerts**: Configure which events trigger notifications.
* **Integration Flexibility**: Connect Firefly events with other tools through Torq.

> **Note:** In the integration settings page, use the notifcation test button to test the integration.


# Webex

Firefly integrates with Webex to provide seamless communication and notification capabilities. This integration enables teams to receive infrastructure alerts, policy violations, and other critical events directly in their Webex spaces.

## Prerequisites

* A Webex account with administrative access.
* Appropriate permissions to create integrations.
* Access to Firefly's integration settings.

## Setup Procedure

1. Install the Firefly Webex integration:
   * Visit [Webex authorization page](https://webexapis.com/v1/authorize?client_id=C90f66d933b7fd81e478c983f02f007a5f132ff053d289badb2f822af3d71344b\&response_type=code\&redirect_uri=https://app.firefly.ai/integrations/webex-integration\&scope=spark%3Amemberships_read%20spark%3Akms%20spark%3Arooms_read%20spark%3Amemberships_write) to authorize the integration.
   * Select **Accept** to authorize the integration.
2. In Firefly, click **Settings > Integrations**.
3. Click **Add New > Webex**.
4. Enter a descriptive name in the **Nickname** field.
5. (Optional) Create a new label for better organization.
6. Click **Next**.
7. Click **Done**.

## Features Enabled

* **Direct Messaging**: Send notifications to specific Webex users.
* **Space Notifications**: Post alerts to designated Webex spaces.
* **Rich Message Formatting**: Enhanced message formatting for better readability.
* **Team Collaboration**: Enable team-wide communication about infrastructure events.
* **Real-time Updates**: Instant notification delivery.

> **Note:** In the integration settings page, use the notifcation test button to test the integration.


# Google Chat

Firefly integrates with Google Chat to provide rich notifications for various events and alerts. This integration enables teams to receive real-time updates about infrastructure changes, policy violations, drift detection, and other important events directly in their Google Chat spaces.

## Prerequisites

* A Google Workspace account with administrative access.
* Appropriate permissions to create webhooks.
* A Google Chat space where you want to receive Firefly notifications.

## Setup Procedure

1. Go to [Google Chat](https://mail.google.com/mail/u/0/#chat/home).
2. Click **New Chat > Create a space**.
3. Click your space name > **Apps & Integrations > Add webhooks**.
4. Add a descriptive name for your webhook and click **Save**.
5. Copy the generated Webhook URL.
6. In Firefly, click **Settings > Integrations**.
7. Click **Add New > Google Chat**.
8. Enter a descriptive name in the **Nickname** field.
9. Paste the webhook URL.
10. Click **Next**.
11. Click **Done**.

## Features Enabled

* **Real-time Notifications**: Receive immediate alerts for important events.
* **Rich Message Formatting**: Detailed, formatted messages with direct links to Firefly.
* **Customizable Alerts**: Configure which events trigger notifications.
* **Space-specific Routing**: Send different types of alerts to different spaces.
* **Interactive Messages**: Click through to Firefly directly from Google Chat notifications.

> **Note:** In the integration settings page, use the notifcation test button to test the integration.




---

[Next Page](/llms-full.txt/1)

