{"id":18995570,"url":"https://github.com/turbot/flowpipe-mod-azure-tags","last_synced_at":"2026-02-03T20:03:03.935Z","repository":{"id":254060742,"uuid":"812985362","full_name":"turbot/flowpipe-mod-azure-tags","owner":"turbot","description":"Run pipelines to detect and correct Azure tags which are missing, prohibited or otherwise unexpected.","archived":false,"fork":false,"pushed_at":"2024-11-28T07:43:20.000Z","size":266,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-12T07:36:09.980Z","etag":null,"topics":["azure","flowpipe","flowpipe-mod","hacktoberfest","hcl","low-code","tagging","tags"],"latest_commit_sha":null,"homepage":"https://hub.flowpipe.io/mods/turbot/azure_tags","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turbot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-10T09:34:25.000Z","updated_at":"2024-11-28T07:42:58.000Z","dependencies_parsed_at":"2025-04-16T19:53:42.671Z","dependency_job_id":"f3b0a28e-9b1e-45f7-8dcc-20c6796e3eff","html_url":"https://github.com/turbot/flowpipe-mod-azure-tags","commit_stats":null,"previous_names":["turbot/flowpipe-mod-azure-tags"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/turbot/flowpipe-mod-azure-tags","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbot%2Fflowpipe-mod-azure-tags","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbot%2Fflowpipe-mod-azure-tags/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbot%2Fflowpipe-mod-azure-tags/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbot%2Fflowpipe-mod-azure-tags/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turbot","download_url":"https://codeload.github.com/turbot/flowpipe-mod-azure-tags/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbot%2Fflowpipe-mod-azure-tags/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29055611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T15:43:47.601Z","status":"ssl_error","status_checked_at":"2026-02-03T15:43:46.709Z","response_time":96,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","flowpipe","flowpipe-mod","hacktoberfest","hcl","low-code","tagging","tags"],"created_at":"2024-11-08T17:31:45.210Z","updated_at":"2026-02-03T20:03:03.919Z","avatar_url":"https://github.com/turbot.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Azure Tags mod for Flowpipe\n\nPipelines to detect and correct Azure resource tag keys and values based on a provided ruleset.\n\n## Documentation\n\n- **[Hub →](https://hub.flowpipe.io/mods/turbot/azure_tags)**\n\n## Getting Started\n\n### Requirements\n\nDocker daemon must be installed and running. Please see [Install Docker Engine](https://docs.docker.com/engine/install/) for more information.\n\n### Installation\n\nDownload and install [Flowpipe](https://flowpipe.io/downloads) and [Steampipe](https://steampipe.io/downloads). Or use Brew:\n\n```sh\nbrew install turbot/tap/flowpipe\nbrew install turbot/tap/steampipe\n```\n\nInstall the Azure plugin with [Steampipe](https://steampipe.io):\n\n```sh\nsteampipe plugin install azure\n```\n\nSteampipe will automatically use your default Azure credentials. Optionally, you can [setup multiple subscriptions](https://hub.steampipe.io/plugins/turbot/azure#multi-subscription-connections) or [configure specific Azure credentials](https://hub.steampipe.io/plugins/turbot/azure#configuring-azure-credentials).\n\nCreate a [`connection_import`](https://flowpipe.io/docs/reference/config-files/connection_import) resource to import your Steampipe Azure connections:\n\n```sh\nvi ~/.flowpipe/config/azure.fpc\n```\n\n```hcl\nconnection_import \"azure\" {\n  source      = \"~/.steampipe/config/azure.spc\"\n  connections = [\"*\"]\n}\n```\n\nFor more information on connections in Flowpipe, please see [Managing Connections](https://flowpipe.io/docs/run/connections).\n\nInstall the mod:\n\n```sh\nmkdir azure-tags\ncd azure-tags\nflowpipe mod install github.com/turbot/flowpipe-mod-azure-tags\n```\n\n### Configuration\n\nTo start using this mod, you may need to configure some [input variables](https://flowpipe.io/docs/build/mod-variables#input-variables).\n\nThe simplest way to do this is to copy the example file `flowpipe.fpvars.example` to `flowpipe.fpvars`, and then update the values as needed. Alternatively, you can pass the variables directly via the command line or environment variables. For more details on these methods, see [passing input variables](https://flowpipe.io/docs/build/mod-variables#passing-input-variables).\n\n```sh\ncp flowpipe.fpvars.example flowpipe.fpvars\nvi flowpipe.fpvars\n```\n\nWhile most [variables](https://hub.flowpipe.io/mods/turbot/azure_tags/variables) are set with sensible defaults, you will need to specify your own tagging rules either as a [base ruleset](#configuring-tag-rules), [resource-specific ruleset](#resource-specific-tag-rules) or a combination of both.\n\n### Configuring Tag Rules\n\nThe `base_tag_rules` variable is an object defined as below. It allows you to specify how tags should be managed on your resources. Let's break down each attribute and how you can configure it for specific use cases.\n\n```hcl\nvariable \"base_tag_rules\" {\n  type = object({\n    add           = optional(map(string))\n    remove        = optional(list(string))\n    remove_except = optional(list(string))\n    update_keys   = optional(map(list(string)))\n    update_values = optional(map(map(list(string))))\n  })\n}\n```\n\n#### Add: Ensuring Resources Have Mandatory Tags\n\nIf you require all your resources to have a set of predefined tags, you can use the `add` attribute to apply these tags to resources that currently do not have the desired tags, along with a default value.\n\nLet's say we want to ensure every resource has the `environment` and `owner` tags. We could write this rule as:\n\n```hcl\nbase_tag_rules = {\n  add = {\n    environment = \"unknown\"\n    owner       = \"turbie\"\n  }\n}\n```\n\nHere, the map key is the tag you want to ensure exists on your resources, and the value is the default value to apply.\n\n#### Remove: Ensuring Resources Don't Have Prohibited Tags \n\nOver time, tags can accumulate on your resources for various reasons. You can use the `remove` attribute to clean up tags that are no longer wanted or allowed from your resources.\n\nIf we wanted to ensure that we didn't include `password`, `secret` or `key` tags on our resources, we could write this rule as:\n\n```hcl\nbase_tag_rules = {\n  remove = [\"password\", \"secret\", \"key\"]\n}\n```\n\nHowever, the above will only cater to exact matches on those strings. This means we may miss tags like `Password` or `ssh_key` as these tags are in a different casing or contain extraneous characters. To achieve better matching we can use patterns along with [supported operators](#supported-operators) in the format `operator:pattern`.\n\nThis would allow us to write rules which match more realistic circumstances and remove tags that contain `password`, begin with `secret`, or end with `key` regardless of the casing.\n\n```hcl\nbase_tag_rules = {\n  remove = [\"~*:password\", \"ilike:secret%\", \"~*:key$\"]\n}\n```\n\nThis allows us to remove any tags which match any of the defined patterns.\n\n#### Remove Except: Ensuring Resources Only Have Permitted Tags\n\nAnother approach to cleaning up your tags is to ensure that you only keep those that are desired or permitted and remove all others. You can use the `remove_except` attribute to define a list of patterns for retaining matching tags, while all other tags are removed.\n\nSince this is the inverse behavior of `remove`, it's best to use one or the other to avoid conflicts. Both follow the same `operator:pattern` matching behavior.\n\nLets say we want to ensure our resources **only** have the following tags:\n- `environment`\n- `owner`\n- `cost_center`\n- Any that are prefixed with our company name `turbot`\n\nWe can write this rule as:\n\n```hcl\nbase_tag_rules = {\n  remove_except = [\"environment\", \"owner\", \"cost_center\", \"~:^turbot\"]\n}\n```\n\nAny tags which do not match one of the above patterns will be removed from the resources.\n\n#### Update Keys: Ensuring Tag Keys Are Standardized\n\nOver time your tagging standards may change, or you may have variants of the same tag that you wish to standardize. You can use the `update_keys` attribute to reconcile tags to a standardized set.\n\nPreviously, we may have used shorthand tags like `env` or `cc` which we want to reconcile to our new standard `environment` and `cost_center`. We may also have encountered common spelling errors such as `enviroment` or `cost_centre`. To standardize these tags, we can write the rule as:\n\n```hcl\nbase_tag_rules = {\n  update_keys = {\n    environment = [\"env\", \"ilike:enviro%\"]\n    cost_center = [\"~*:^cc$\", \"~*:^cost_cent(er|re)$\", \"~*:^costcent(er|re)$\"]\n  }\n}\n```\n\nBehind the scenes, this works by creating a new tag with the value of existing matched tag and then removing the existing matched tag.\n\n#### Update Values: Ensuring Tag Values Are Standardized\n\nJust like keys, you may want to standardize the values over time or correct common typos. You can use the `update_values` attribute to reconcile values to expected standards.\n\nThis works in a similar way to `update_keys` but has an extra layer of nesting to group the updates on a per-key basis. The outer map key is the tag key, the inner map key is the new value, and the patterns are used for matching the existing values.\n\nPreviously, we may have used shorthand or aliases for tag values that we now want to standardize. For instance:\n- For the `environment` tag, any previous shorthand or aliases should be standardized to the full names.\n- For the `cost_center` tag, any values containing non-numeric characters should be replaced by a default cost center.\n- For the `owner` tag, any resources previously owned by _nathan_ or _Dave_ should now be owned by _bob_.\n\nLet's write these rules as follows:\n\n```hcl\nbase_tag_rules = {\n  update_values = {\n    environment = {\n      production        = [\"~*:^prod\"]\n      test              = [\"~*:^test\", \"~*:^uat$\"]\n      quality_assurance = [\"~*:^qa$\", \"ilike:%qual%\"]\n      development       = [\"~*:^dev\"]\n    }\n    cost_center = {\n      \"0123456789\" = [\"~:[^0-9]\"]\n    }\n    owner = {\n      bob = [\"~*:^nathan$\", \"ilike:Dave\"]\n    }\n  }\n}\n```\n\nAdditionally, for a given key we can specify a default to use for the tags value when no other patterns match using a special `else:` operator. This is especially useful when you want to ensure that all values are updated to a standard without knowing all potential matches.\n\nLet's say that we want any `environment` with a value not matching our patterns for `production`, `test` or `quality_assurance` to default to `development`. We could rewrite our rule as below:\n\n```hcl\nbase_tag_rules = {\n  update_values = {\n    environment = {\n      production        = [\"~*:^prod\"]\n      test              = [\"~*:^test\", \"~*:^uat$\"]\n      quality_assurance = [\"~*:^qa$\", \"ilike:%qual%\"]\n      development       = [\"else:\"]\n    }\n    cost_center = {\n      \"0123456789\" = [\"~:[^0-9]\"]\n    }\n    owner = {\n      bob = [\"~*:^nathan$\", \"ilike:Dave\"]\n    }\n  }\n}\n```\n\n\u003e Note: While it is possible to have multiple `else:` patterns declared for any given tag, only the one with the first alphabetically sorted value (inner map key) will be used.\n\nIn this configuration:\n\n- The `environment` tag values like `prod`, `qa`, and `uat` will be standardized to `production`, `quality_assurance`, and `test`, respectively. Any unmatched values will default to `development`.\n- The `cost_center` tag values that contain non-numeric characters will be replaced with `0123456789`.\n- The `owner` tag values `Nathan` and `Dave` will be changed to `bob`.\n\nThis approach ensures that all your tag values are consistently updated, even when new or unexpected values are encountered.\n\n#### Complete Tag Rules\n\nNow that you understand each of the attributes available in the `base_tag_rules` object individually, you can combine them to create a complex ruleset for managing your resource tags. By leveraging multiple attributes together you can achieve sophisticated tagging strategies.\n\n\u003e Note: Using `remove` / `remove_except`\n\u003e\n\u003e Ideally, you should use either the `remove` or the `remove_except` attribute, but not both simultaneously. This ensures clarity in your tag removal logic and avoids potential conflicts.\n\u003e\n\u003e - `remove`: Use this to specify patterns of tags you want to explicitly remove.\n\u003e - `remove_except`: Use this to specify patterns of tags you want to retain, removing all others.\n\nWhen using a combination of attributes to build a complex ruleset, they will be executed in the following order to ensure logical application of the rules:\n\n1. `update_keys`: Start by updating any incorrect keys to the new expected values.\n2. `add`: Add missing mandatory tags with a default value. This is done after updating the keys to ensure that if update has the same tag, the value isn't overwritten with the default but kept.\n3. `remove`/`remove_except`: Remove any tags no longer required based on the patterns provided and old tags which have been updated.\n4. `update_values`: Finally once the tags have been established, the values will be reconciled as desired.\n\nLets combine some of the above examples to create a complex ruleset.\n\n```hcl\nbase_tag_rules = {\n  update_keys = {\n    environment = [\"env\", \"ilike:enviro%\"]\n    cost_center = [\"cc\", \"~*:^cost_cent(er|re)$\", \"~*:^costcent(er|re)$\"]\n  }\n  add = {\n    environment = \"unknown\"\n    owner       = \"turbie\"\n    cost_center = \"0123456789\"\n  }\n  remove_except = [\n    \"environment\", \n    \"owner\", \n    \"cost_center\", \n    \"~:^turbot\"\n  ]\n  update_values = {\n    environment = {\n      production        = [\"~*:^prod\"]\n      test              = [\"~*:^test\", \"~*:^uat$\"]\n      development       = [\"~*:^dev\"]\n      quality_assurance = [\"~*:^qa$\", \"ilike:%quality%\"]\n    }\n    cost_center = {\n      \"0123456789\" = [\"~:[^0-9]\"]\n    }\n    owner = {\n      bob = [\"~*:^nathan$\", \"ilike:Dave\"]\n    }\n  }\n}\n```\n\nThis ensures that:\n- Firstly, the keys are updated, so we can safely perform the next rules on those keys.\n- Secondly, any missing required tags are added.\n- Thirdly, any tags that are no longer required are removed.\n- Finally, the values are updated as required.\n\n#### Resource-Specific Tag Rules\n\nYou have three options for defining tag rules:\n\n1. Only provide `base_tag_rules`: Apply the same rules to every resource.\n2. Omit `base_tag_rules` and only provide resource-specific rules (e.g. `storage_accounts_tag_rules`): Allow for custom rules per resource.\n3. Provide both `base_tag_rules` and resource-specific rules: Merge the rules to create a comprehensive ruleset.\n\nWhen merging the `base_tag_rules` with resource-specific rules, the following behaviors apply:\n\n- **Maps** (e.g., `add`, `update_keys`, `update_values`): The maps from the resource-specific rules will be merged with the corresponding maps in the `base_tag_rules`. If a key exists in both the base rules and the resource-specific rules, the value from the resource-specific rules will take precedence.\n- **Lists** (e.g., `remove`, `remove_except`): The lists from both the base and resource-specific rules will be merged/concatenated and then deduplicated to ensure that all unique entries from both lists are included.\n\nLet's say you have base_tag_rules defined as follows:\n\n```hcl\nbase_tag_rules = {\n  add = {\n    environment = \"unknown\"\n    cost_center = \"0123456789\"\n    owner       = \"turbie\"\n  }\n  remove = [\"~*:password\", \"ilike:secret%\"]\n  remove_except = []\n  update_keys = {\n    environment = [\"env\", \"ilike:enviro%\"]\n    cost_center = [\"cc\", \"~*:^cost_cent(er|re)$\", \"~*:^costcent(er|re)$\"]\n  }\n  update_values = {\n    environment = {\n      production        = [\"~*:^prod\"]\n      test              = [\"~*:^test\", \"~*:^uat$\"]\n      development       = [\"~*:^dev\"]\n      quality_assurance = [\"~*:^qa$\", \"ilike:%quality%\"]\n    }\n    cost_center = {\n      \"0123456789\" = [\"~:[^0-9]\"]\n    }\n    owner = {\n      bob = [\"~*:^nathan$\", \"ilike:Dave\"]\n    }\n  }\n}\n```\n\nAnd you want to apply additional rules to storage accounts:\n\n```hcl\nstorage_accounts_tag_rules = {\n  add = {\n    resource_type = \"bucket\"\n  }\n  remove = [\"ilike:secret%\", \"~*:key$\"]\n  remove_except = []\n  update_keys = {\n    environment = [\"~*:^env\"]\n    owner       = [\"~*:^owner$\", \"~*:manager$\"]\n  }\n  update_values = {\n    owner = {\n      bob = [\"~*:^dave$\"]\n    }\n  }\n}\n```\n\nWhen merged, the resulting tag rules for storage accounts will be:\n\n```hcl\n{\n  add = {\n    environment   = \"unknown\"\n    cost_center   = \"0123456789\"\n    owner         = \"turbie\"\n    resource_type = \"bucket\"\n  }\n  remove = [\"~*:password\", \"ilike:secret%\", \"~*:key$\"]\n  remove_except = []\n  update_keys = {\n    environment = [\"~*:^env\"]\n    cost_center = [\"cc\", \"~*:^cost_cent(er|re)$\", \"~*:^costcent(er|re)$\"]\n    owner       = [\"~*:^owner$\", \"~*:manager$\"]\n  }\n  update_values = {\n    environment = {\n      production        = [\"~*:^prod\"]\n      test              = [\"~*:^test\", \"~*:^uat$\"]\n      development       = [\"~*:^dev\"]\n      quality_assurance = [\"~*:^qa$\", \"ilike:%quality%\"]\n    }\n    cost_center = {\n      \"0123456789\" = [\"~:[^0-9]\"]\n    }\n    owner = {\n      bob = [\"~*:^dave$\"]\n    }\n  }\n}\n```\n\nIn this example:\n\n- The `add` map includes entries from both `base_tag_rules` and `storage_accounts_tag_rules`.\n- The `remove` list is a concatenation of entries from both lists, ensuring no duplicates (`\"ilike:secret%\"` appears only once).\n- The `remove_except` list remains empty as specified in both rules.\n- The `update_keys` map merges entries, with the resource-specific rules for environment and owner overriding the base rules entirely.\n- The `update_values` map shows that the resource-specific rule for `owner` overrides the base rule for the same key.\n\nBy providing resource-specific tag rules, you can customize and extend the base tagging strategy to meet the unique requirements of individual resources, ensuring flexibility and consistency in your tag management.\n\n#### Supported Operators\n\nThe below table shows the currently supported operators for pattern-matching.\n\n| Operator | Purpose |\n| -------- | ------- |\n| `=`      | Case-sensitive exact match |\n| `like`   | Case-sensitive pattern matching, where `%` indicates zero or more characters and `_` indicates a single character. |\n| `ilike`  | Case-insensitive pattern matching, where `%` indicates zero or more characters and `_` indicates a single character. |\n| `~`      | Case-sensitive pattern matching using `regex` patterns. | \n| `~*`     | Case-insensitive pattern matching using `regex` patterns. | \n| `else:`  | _Special Operator_ only supported in `update_values` to indicate that this value should be used as replacement value if no other pattern is matched. The whole value must be an _exact match_ of `else:` with no trailing information. |\n\nIf you attempt to use an operator *not* in the table above, the string will be processed as an exact match.\nFor example,  `!~:^bob` wouldn't match anything that doesn't begin with `bob`; instead, it would only match if the key/value is exactly `!~:^bob`.\n\n### Running Pipelines\n\nThis mod contains a few different types of pipelines:\n- `detect_and_correct`: these are the core pipelines intended for use, they will utilise [Steampipe](https://steampipe.io) queries to determine amendments to your tags based on the provided ruleset(s).\n- `correct` / `correct_one`: these pipelines are designed to be fed from the `detect_and_correct` pipelines, albeit they've been separated out to allow you to utilise your own detections if desired, this is an advanced use-case however, thus won't be covered in this documentation.\n- Other `utility` type pipelines such as `add_and_remove_resource_tags`, these are designed to be used by other pipelines and should only be called directly if you've read and understood the functionality.\n\nLet's begin by looking at how to run a `detect_and_correct` pipeline, assuming you've already followed the [installation instructions](#installation) and [configured tag rules](#configuring-tag-rules) as required\n\n\nFirstly, we need to ensure that [Steampipe](https://steampipe.io) is running in [service mode](https://steampipe.io/docs/managing/service).\n\n```sh\nsteampipe service start\n```\n\nThe pipeline we want to run will be `detect_and_correct_\u003cresource_type\u003e_with_incorrect_tags`, we can find those available by running the following command:\n\n```sh\nflowpipe pipeline list | grep \"detect_and_correct\"\n```\n\nThen run your chosen pipeline, for example if we wish to remediate tags on our `storage accounts`:\n```sh\nflowpipe pipeline run azure_tags.pipeline.detect_and_correct_storage_accounts_with_incorrect_tags --var-file flowpipe.fpvars\n```\n\nThis will then run the pipeline and depending on your configured running mode; perform the relevant action(s), there are 3 running modes:\n- Wizard\n- Notify\n- Automatic\n\n#### Wizard\nThis is the `default` running mode, allowing for a hands-on approach to approving changes to resource tags by prompting for [input](https://flowpipe.io/docs/build/input) for each resource detected violating the provided ruleset.\n\nWhile the out of the box default is to run the workflow directly in the terminal. You can use Flowpipe [server](https://flowpipe.io/docs/run/server) and [external integrations](https://flowpipe.io/docs/build/input) to prompt in `http`, `slack`, `teams`, etc.\n\n#### Notify\nThis mode as the name implies is used purely to report detections via notifications either directly to your terminal when running in client mode or via another configured [notifier](https://flowpipe.io/docs/reference/config-files/notifier) when running in server mode for each resource that violated a tagging rule along with the suggested remedial action.\n\nTo run in `notify` mode, you will need to set the `approvers` variable to an empty list `[]` and ensure the`incorrect_tags_default_action` variable is set to `notify`, either in your fpvars file\n\n```hcl\n# flowpipe.fpvars\napprovers = []\nincorrect_tags_default_action = \"notify\"\nbase_tag_rules = ... # omitted for brevity\n```\n\nor pass the `approvers` and `default_action` arguments on the command-line.\n\n```sh\nflowpipe pipeline run azure_tags.pipeline.detect_and_correct_storage_accounts_with_incorrect_tags --var-file flowpipe.fpvars --arg='default_action=notify' --arg='approvers=[]'\n```\n\n#### Automatic\nThis behavior allows for a hands-off approach to remediating (or ignoring) your tagging ruleset violations.\n\nTo run in `automatic` mode, you will need to set the `approvers` variable to an empty list `[]` and the `incorrect_tags_default_action` variable to either `skip` or `apply` in your fpvars file\n\n```hcl\n# flowpipe.fpvars\napprovers = []\nincorrect_tags_default_action = \"apply\"\nbase_tag_rules = ... # omitted for brevity\n```\n\nor pass the `default_action` argument on the command-line.\n\n```sh\nflowpipe pipeline run azure_tags.pipeline.detect_and_correct_storage_accounts_with_incorrect_tags --var-file flowpipe.fpvars --arg='default_action=apply'\n```\n\nTo further enhance this approach, you can enable the pipelines corresponding [query trigger](#running-query-triggers) to run completely hands-off.\n\n### Running Query Triggers\n\n\u003e Note: Query triggers require Flowpipe running in [server](https://flowpipe.io/docs/run/server) mode.\n\nEach `detect_and_correct` pipeline comes with a corresponding [Query Trigger](https://flowpipe.io/docs/flowpipe-hcl/trigger/query), these are _disabled_ by default allowing for you to _enable_ and _schedule_ them as desired.\n\nLet's begin by looking at how to set-up a Query Trigger to automatically resolve tagging violations with our storage accounts.\n\nFirsty, we need to update our `flowpipe.fpvars` file to add or update the following variables - if we want to run our remediation `hourly` and automatically `apply` the corrections:\n\n```hcl\n# flowpipe.fpvars\n\nstorage_accounts_with_incorrect_tags_trigger_enabled  = true\nstorage_accounts_with_incorrect_tags_trigger_schedule = \"1h\"\nincorrect_tags_default_action                         = \"apply\"\n\nbase_tag_rules = ... # omitted for brevity\n```\n\nNow we'll need to start up our Flowpipe server:\n\n```sh\nflowpipe server --var-file=flowpipe.fpvars\n```\n\nThis will activate every hour and detect storage accounts with tagging violations and apply the corrections without further interaction!\n\n#### Detection Differences: Query Trigger vs Pipeline\n\nWhen running the `detect_and_correct` paths, there is a key difference in the detections returned when using a query trigger vs calling the pipeline.\n\nThis is due to the query trigger caching the result set, therefore once a resource has been detected, if it is skipped it will not be returned in future detections until the query trigger cache is cleared or the resource is removed by a run of the query trigger where the result is ok.\n\n## Open Source \u0026 Contributing\n\nThis repository is published under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Please see our [code of conduct](https://github.com/turbot/.github/blob/main/CODE_OF_CONDUCT.md). We look forward to collaborating with you!\n\n[Flowpipe](https://flowpipe.io) and [Steampipe](https://steampipe.io) are products produced from this open source software, exclusively by [Turbot HQ, Inc](https://turbot.com). They are distributed under our commercial terms. Others are allowed to make their own distribution of the software, but cannot use any of the Turbot trademarks, cloud services, etc. You can learn more in our [Open Source FAQ](https://turbot.com/open-source).\n\n## Get Involved\n\n**[Join #flowpipe on Slack →](https://turbot.com/community/join)**\n\nWant to help but don't know where to start? Pick up one of the `help wanted` issues:\n\n- [Flowpipe](https://github.com/turbot/flowpipe/labels/help%20wanted)\n- [Azure Tags Mod](https://github.com/turbot/flowpipe-mod-azure-tags/labels/help%20wanted)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturbot%2Fflowpipe-mod-azure-tags","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturbot%2Fflowpipe-mod-azure-tags","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturbot%2Fflowpipe-mod-azure-tags/lists"}