In most Azure environments, especially ones that have grown organically over time, you’ll find plenty of resources that were originally created through the Azure Portal. ClickOps, that habit of clicking through blades and spinning up resources manually, is still extremely common. Even in teams that use Terraform or Bicep, ClickOps shows up when someone’s troubleshooting, testing something quickly, or just trying to unblock a release.

The problem is, those portal-based changes often fall outside version control. There’s no pull request, no audit trail in Git, and no easy way to track what changed, or worse, who changed it. When your IaC runs again, those manual changes either get overwritten or cause drift warnings. That leads to broken pipelines, unexpected diffs, or inconsistent environments.

There was a good thread on r/Terraform where someone asked how to deal with resources that were created manually. Most replies pointed to terraform import, which is useful for bringing unmanaged resources under control. It works, but only after the fact. It doesn’t tell you what was changed, when, or why. And it definitely doesn’t help you catch those changes in real time.

That’s where Firefly comes in.

This blog walks through how Firefly Event Center detects ClickOps activity in Azure and logs every configuration change as a mutation event, with full context, before/after diffs, and metadata. Whether the change comes from the Portal, the CLI, Terraform, or the SDK, Firefly shows you exactly what changed, and who did it. It’s a practical way to regain visibility, even if the Portal is still part of your day-to-day operations.

What Is ClickOps in Azure

ClickOps is what most people start with in Azure: opening the portal, clicking through a few blades, and provisioning resources manually. You pick a service, fill in a few fields, hit “Review + Create,” and you’re done. No code, no pipelines, no IaC.

It’s convenient, especially when you’re trying something out, fixing something quickly, or just not ready to set up Terraform or Bicep. Think of it like this: suddenly, your web app becomes unresponsive, and to troubleshoot, you quickly open an inbound NSG rule or allow 0.0.0.0/0 on a port “just to check.” The app starts working again, the customer is happy, you’re happy, and you go home. But you never revert to the rule. There was no CI pipeline to catch it, no .tf state file to track it, and no one noticed until a security engineer flagged it a week later.

That’s the key thing about ClickOps: it bypasses your Infrastructure as Code process. There’s no .tf file or ARM template representing what you did, no version history in Git. You’re changing the live environment directly, and those changes won’t show up in your IaC plan unless you explicitly import them or reconcile the state.

Even in IaC-first teams, ClickOps creeps back in. Someone needs to fix a prod issue fast and doesn’t want to wait on a CI pipeline. Someone else wants to test a config in the dev subscription before they write it as code. Before long, you’ve got real changes happening outside of code, and no clear visibility into what’s being modified.

Firefly treats those changes as first-class events. When someone makes a change in the Azure Portal, Firefly flags it as a ClickOps event and logs it with full metadata: who made it, when, from where, and what changed. That’s the first step to getting control back—not just enforcing IaC, but actually seeing what happens when it’s bypassed.

In the snapshot below, you can see Firefly’s Dashboard highlighting “ClickOps Events (last week)”, giving you instant visibility into unmanaged console changes across your multi-cloud environment:

Firefly’s Dashboard highlighting “ClickOps Events (last week)”, giving you instant visibility into unmanaged console changes across your multi-cloud environment

How Azure Emits and Forwards Change Events

Before Firefly (or any external system) can detect ClickOps and mutations, Azure needs to emit those change events in a structured, trackable way. This happens via Azure’s control plane telemetry, which captures operations like resource creation, deletion, and configuration changes across the platform.

To surface these events outside of Azure, a few native resources must be configured at the subscription level. These are the backbone of any real-time event tracking setup.

Azure Monitor Diagnostic

This is what tells Azure to emit Activity Logs for key control plane actions like PUT, PATCH, or DELETE. It’s the starting point; no diagnostic setting means no outbound telemetry.

Event Grid System

Once logs are emitted, Event Grid acts as the first-party event source. It’s tightly integrated with Azure Monitor and is aware of new mutation events as they happen, with no need for polling or scanning.

Event Subscription

This subscription binds the system topic to a destination (like Event Hubs or an external processor). It’s how the telemetry stream leaves Azure. Every update or manual portal change can be routed downstream in near real time.

Storage Account

If you also need long-term retention, logs can be pushed to a storage account in structured hourly blobs. This is especially helpful for audit trails, point-in-time recovery, or backfilling gaps in downstream processing.

What Would You Do Without Firefly?

Before moving to Firefly, most Azure teams relied on a mix of these manual approaches to detect and manage changes:

Manual Log Digging

You sift through Azure Activity Logs, filtering by operation types like PUT or DELETE to identify what changed.

  • But there’s no before/after diff to compare the change.
  • It’s hard to tell if the change was made from ClickOps or IaC.
  • You only get a timestamp and a username — no context on the actual change.

Relying on terraform plan

You run terraform plan to detect drift between your live environment and your code.

  • Drift is only detected when the pipeline runs.
  • By that point, someone might have already made manual changes that cause issues.
  • You can see what’s different, but you won’t know who made the change or why.

Spreadsheet Governance

Some teams try to track resources with tags (e.g., managed_by=terraform) or maintain a shared spreadsheet listing which resources are managed by IaC.

  • But it’s manual and depends on consistency.
  • If someone creates resources in the Portal, they might forget to tag them.
  • No enforcement means these systems break down quickly and become unreliable.

Custom Alerting Setups

Some teams try to build custom alerting setups by sending Activity Logs to Event Grid or external tools like Splunk.

  • They might catch certain events but still miss crucial details like before/after diffs, or who initiated the change.
  • These setups lack context and are time-consuming to manage.

These methods fail because they’re reactive and lack real-time detection. With manual log digging, you only discover changes after they’ve caused issues. Terraform plan detects drift too late, while spreadsheet governance relies on manual updates, with multiple errors. Custom alerting setups often miss critical changes or lack context. As a result, you end up re-importing resources or recreating configurations, instead of preventing problems early.

Now, let’s see how Firefly addresses these challenges by providing real-time detection and full context for every change.

How Firefly Detects ClickOps and Infrastructure Mutations

Firefly integrates directly with Azure’s control plane. Instead of relying on drift detection via periodic terraform plan or polling for state diffs, Firefly hooks into Azure Activity Logs and Event Grid to ingest real-time telemetry about resource mutations. This lets Firefly detect and record every change, whether triggered through the Portal (ClickOps), CLI, SDK, or Terraform, as soon as it happens.

What Firefly Tracks in Azure Activity Logs

Once you've configured Diagnostic Settings and wired up Event Grid (usually via Firefly’s onboarding Terraform module), Firefly begins ingesting the following control-plane operations:

  • PUT, PATCH, and DELETE operations: Any configuration-level change, like enabling a property, updating a policy, or deleting a resource, Firefly sees it the moment Azure emits it.
  • Caller identity: Whether the change came from a user, service principal, system-assigned identity, or managed app, Firefly logs exactly who initiated the change.
  • Source of execution: Firefly distinguishes whether the operation came from:
    • Azure Portal → flagged as ClickOps
    • Azure CLI / PowerShell / SDK → categorized as manual/scripted
    • Terraform / Bicep / IaC engine → inferred via change patterns and source metadata
  • Before/After Configuration Diff
    Firefly reconstructs the payloads before and after the change to show exactly what was modified, similar to how you'd review a Git commit.

In the screenshot below, you can see Firefly’s Event Center in action. It lists multiple recent Azure events with clear details, such as the data source, location, asset type, event name, and owner:

You can easily filter ClickOps and Mutations by time range, data source, location, and action type to pinpoint exactly when and where manual or unmanaged changes happened.

How the Detection in Firefly Works

  • Event Collection: Firefly consumes Azure Activity Logs using Event Grid Subscriptions. These logs capture control-plane changes like resource creation, updates, deletions, and role assignments, but not data-plane operations (e.g., reading blobs or querying SQL).
  • Event Enrichment: Every raw event is enriched with:

    • Identity of the owner (including full Azure AD context)
    • Operation type (e.g., Microsoft.Compute/virtualMachines/write)
    • Source (Portal, CLI, IaC)
    • Resource scope and location
    • Raw request/response data

  • Event Classification
    Firefly applies internal logic to classify events into:
    • clickops: manual changes via the Portal
    • cli_or_sdk: programmatic changes from az CLI, PowerShell, or client SDKs
    • mutation: any change that impacts resource configuration, whether scripted or manual

Each event is stored in Firefly’s Event Center, with full context and timestamps for auditability.

Tracking ClickOps in Firefly’s Event Center

Firefly’s Event Center displays a series of ClickOps events, manual changes made via the Azure Portal UI

In the snapshot above, Firefly’s Event Center displays a series of ClickOps events, manual changes made via the Azure Portal UI.

Let’s focus on this specific event:

  • Operation: Microsoft.Storage/storageAccounts/write
  • Resource: weblog1 (Storage Blob)
  • Region: Central India
  • Timestamp: 2025-07-15T12:30:14Z
  • Owner: ******************@gmail.com
  • Event Type: ClickOps
  • Data Source: Azure Activity Logs
  • Agent: Azure Portal (inferred from user-agent string)

Firefly flagged this as ClickOps because:

  • The source of the event was the Azure Portal
  • The operation was a control-plane write (storageAccounts/write)
  • The change was initiated by a user, not an IaC or automation tool
  • Firefly’s ingestion pipeline identified it as a manual intervention outside version control.

In addition to ClickOps events, Firefly also tracks mutation events. These capture any configuration changes, including the creation or modification of resources such as Storage Blobs, and provide detailed before-and-after diffs to show exactly what changed.

This enables real-time tracking of manual changes in Azure, including new resources like Storage Blobs created through the Portal. You can act on these insights immediately, without waiting for the next terraform plan or drift detection to flag the changes.

Resource Correlation: From Event to Inventory

Here’s where Firefly’s Event Center and Inventory work together. When you click on the asset name weblog1 in the event row, Firefly routes you directly to the Inventory view of that exact resource, as shown in the snapshot below:

Firefly routes you directly to the Inventory view of that exact resource

On the Inventory page for weblog1, you’ll immediately see that its IaC Status is marked as Unmanaged, confirming that the resource was not provisioned using Terraform, Bicep, or any other declarative tool. You’ll also find the Azure Resource ID, including its subscription and resource group path, along with its location set to eastus. The data for this resource is sourced from Azure Activity Logs, and you can view the exact creation timestamp as recorded by Azure for clear historical context.

This view confirms the resource was created manually (ClickOps) and is currently not tracked by any Terraform state file, a typical sign of infrastructure drift.

Auto-Generated Terraform Block (Codify)

From the Inventory panel, you can select “Codify” to automatically generate a Terraform block representing the unmanaged resource.

 Inventory panel,

 In this case, Firefly generates a complete azurerm_storage_account block with all detected attributes:

resource "azurerm_storage_account" "weblog1" {
  access_tier                     = "Hot"
  account_kind                    = "StorageV2"
  account_replication_type        = "RAGRS"
  location                        = "eastus"
  name                            = "weblog1"
  public_network_access_enabled   = false
  enable_https_traffic_only       = true
  ...
}

This lets you codify the ClickOps-created resource into Infrastructure as Code without manual guesswork,  and optionally raise a pull request directly from the UI to add the change in your VCS.

How Firefly Helps in Troubleshooting and Monitoring

When something goes wrong in your environment, the first step is to investigate what changed. With Firefly, you can:

  • Trace changes back to the exact action that caused an issue, whether it was a ClickOps event, an IaC deployment, or a manual CLI command.
  • Understand drift: See how the current state differs from your IaC definitions, and track down any manual changes that may have bypassed automation.
  • Quickly react to unexpected changes by setting up alerts for high-priority events (e.g., a Storage Blob being set to public access in production).

Firefly’s Event Center empowers your team to have full visibility over the entire lifecycle of your cloud infrastructure. With easy-to-use filtering, real-time updates, and a detailed history of changes, you can improve operational efficiency and stay on top of potential issues before they disrupt your services.

Best Practices for Azure Teams

To get the most value from Firefly's Event Center and ensure optimal visibility and control over your Azure resources, it’s essential to follow a set of best practices tailored to security, compliance, and operational efficiency.

1. Review ClickOps Events Regularly

Even in environments that rely heavily on Infrastructure as Code (IaC), manual changes through the Azure Portal (ClickOps) can still happen. These changes often go unnoticed, leading to drift and inconsistencies across your environment. To avoid this, it’s recommended to review ClickOps events daily, particularly in production environments. Use Firefly’s filtering features to track changes in critical resources like storage blobs or networking configurations, and set up alerts to notify you of significant changes. This gives you real-time visibility into who made a change and when, preventing potential issues before they escalate.

2. Use terraform import to Bring Unmanaged Resources Under Code

In addition to reviewing ClickOps, you should also use terraform import to bring any manually created or modified resources under IaC management. Firefly helps by tracking these changes in real-time, providing the context you need to bring resources back under version control. By doing so, you ensure all infrastructure changes are managed through your standard IaC tools, maintaining consistency across your environment.

3. Set Up Alerts for Critical Events

Alerts are also critical to maintaining visibility. Firefly allows you to set up real-time notifications for critical events. For instance, if public access is enabled on a storage account or an unexpected deletion occurs, Firefly can immediately alert you, so you can investigate and take action. These alerts can be integrated with your existing monitoring tools like Slack or Teams, ensuring that key team members are notified right away.

4. Enforce Role-Based Access Control (RBAC) and Least Privilege

Another important best practice is enforcing Role-Based Access Control (RBAC) and the principle of least privilege. By restricting permissions to only what is necessary, you limit the risk of unauthorized changes. Firefly's Event Center tracks who makes changes to resources, providing an easy way to audit whether the right people are performing the right actions. Regularly reviewing RBAC policies and using Firefly’s detailed event logs can help ensure your security posture remains strong.

5. Protect Sensitive Data with Azure Key Vault

In terms of data protection, it's crucial to store sensitive information, like keys and secrets, in Azure Key Vault. Firefly tracks changes made to these critical resources, such as changes to access policies, ensuring visibility into who has access and what has changed. Regular audits of access and configuration settings help ensure that your sensitive data remains secure.

Frequently Asked Questions

What is Azure ClickOps?

Azure ClickOps refers to the practice of manually creating or managing resources through the Azure Portal (GUI). Rather than using Infrastructure as Code (IaC) tools like Terraform, Bicep, or ARM templates, users directly interact with the portal to provision, modify, or delete resources. While this method may seem convenient for quick fixes or one-off tasks, it often leads to configuration drift, security gaps, and a lack of version control, which can be mitigated by using IaC tools and monitoring systems like Firefly.

What is Bicep vs Terraform?

Both Bicep and Terraform are tools used for Infrastructure as Code (IaC) in Azure, but they differ in syntax and approach:

  • Bicep is a domain-specific language (DSL) developed by Microsoft as a simpler alternative to Azure Resource Manager (ARM) templates. It's Azure-native and tightly integrated with Azure services, making it a good choice for users who want to stick with Azure-specific tooling.

  • Terraform, on the other hand, is a cross-cloud IaC tool that allows you to manage resources not only in Azure but also in AWS, GCP, and other providers. Terraform is highly extensible, supports a wide range of cloud providers, and has a large community. It uses HCL (HashiCorp Configuration Language), which some developers find more flexible and readable than Bicep.

What is Terraform in Azure?

Terraform in Azure refers to using Terraform as the IaC tool to provision and manage resources within an Azure environment. By defining your infrastructure as code using Terraform, you can automate resource provisioning, enforce consistency, track changes, and version control your Azure infrastructure. Terraform uses Azure’s API to create, modify, or delete resources like Virtual Machines, Storage Accounts, and Networking configurations, while also maintaining the desired state across all Azure environments.

Is Azure now called Entra ID?

No, Azure is not being renamed Entra ID. However, Microsoft has rebranded Azure Active Directory (AAD) to Microsoft Entra ID. 

‍