Skip to content

tidalmigrations/poc-tag-inheritance

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Azure Resource Tagging Inheritance POC

This project demonstrates Azure resource tagging inheritance issues and provides solutions using Pulumi, Azure Resource Graph, and Azure Policy.

Overview

The POC creates an environment where Virtual Machines have proper tags but their attached disks don't inherit those tags, demonstrating a common Azure governance challenge. The project then provides automated solutions to identify and remediate these tagging gaps using Azure Policy implementation for automated tag governance and compliance enforcement. The solution includes custom Azure Policies that audit untagged disks and enforce required tags on VMs, providing a comprehensive approach to tag inheritance and governance.

Prerequisites

Before getting started, ensure you have the following tools installed:

Initial Setup

1. Clone and Initialize the Project

git clone <repository-url>
cd poc-tag-inheritance

2. Azure Authentication

Login to Azure CLI:

az login

Verify your subscription:

az account show

If you need to switch subscriptions:

az account set --subscription "your-subscription-id"

3. Initialize Pulumi with Azure Storage Backend

Run the setup script to create the Azure Storage backend and initialize the Pulumi project:

./setup-pulumi-backend.sh

This script will:

  • βœ… Create a resource group for Pulumi state storage
  • βœ… Create an Azure Storage Account with proper security settings
  • βœ… Create a blob container for state files
  • βœ… Configure Pulumi to use the Azure Storage backend
  • βœ… Initialize the Pulumi project with TypeScript

4. Configure the Pulumi Stack

After running the setup script, configure your Pulumi stack with the required settings:

# Set Azure location
pulumi config set azure-native:location "East US"

# Set your Azure subscription ID (replace with your actual subscription ID)
pulumi config set azure-native:subscriptionId "your-subscription-id"

# Set project-specific configuration
pulumi config set project:name "poc-tag-inheritance"
pulumi config set project:environment "POC"
pulumi config set project:owner "PLACEHOLDER-Team"

# Set VM credentials configuration
pulumi config set vm:adminUsername "azureuser"
pulumi config set vm:adminPassword "P@ssw0rd123!" --secret
pulumi config set vm:disablePasswordAuthentication "false"

To get your Azure subscription ID:

az account show --query id -o tsv

Working with the Project

Logging Back into the Project

If you need to reconnect to the project later (e.g., on a new machine or after logging out), follow these steps:

1. Login to Azure

az login

2. Set Environment Variables for Storage Access

You'll need the storage account name from your initial setup. Check the setup script output or find it in Azure Portal:

export AZURE_STORAGE_ACCOUNT="stpulumitagpoc<timestamp>"
export AZURE_STORAGE_KEY="<your-storage-key>"

To get the storage key:

# Replace with your actual resource group and storage account names
az storage account keys list \
    --resource-group "rg-pulumi-state-poc-tag-inheritance" \
    --account-name "stpulumitagpoc<timestamp>" \
    --query '[0].value' -o tsv

3. Login to Pulumi Backend

pulumi login azblob://pulumi-state

4. Select the Stack

pulumi stack select dev

Quick Reconnect (Alternative)

For convenience, you can use the provided reconnect script that automates the above steps:

source ./reconnect-to-project.sh

Note: Use source to ensure environment variables persist in your current shell session.

This script will automatically:

  • Find your storage account
  • Set the required environment variables
  • Login to the Pulumi backend
  • Select the dev stack

Verify Your Setup

Check that everything is configured correctly:

# Check Pulumi configuration
pulumi config

# Verify all required config values are set
pulumi config get azure-native:location
pulumi config get azure-native:subscriptionId
pulumi config get project:name
pulumi config get project:environment
pulumi config get project:owner

# Verify VM configuration values are set
pulumi config get vm:adminUsername
pulumi config get vm:adminPassword
pulumi config get vm:disablePasswordAuthentication

# Check current stack
pulumi stack

# Preview infrastructure (without deploying)
pulumi preview

POC Infrastructure

The project creates a complete environment to demonstrate the tagging inheritance problem:

Infrastructure Components

  • Resource Group: poc-rg with standard organizational tags
  • Virtual Network: poc-vnet with subnet and network security group
  • Virtual Machines: Two VMs (poc-vm1, poc-vm2) with comprehensive tags
  • Data Disks: Untagged disks attached to the VMs (demonstrating the problem)
  • Network Resources: Public IPs, NICs, and NSG with proper tagging
  • Azure Policies: Custom policy definitions for tag governance
    • Tag Inheritance Policy: Audits disks without inherited tags
    • Required Tags Policy: Enforces required tags on VMs
    • Policy Initiative: Comprehensive tagging governance framework
  • Managed Identity: For policy execution with appropriate permissions

Standard Tags Applied

All properly tagged resources include:

  • Environment: "POC"
  • Project: "TaggingInheritance"
  • Owner: "PLACEHOLDER-Team"
  • CostCenter: "IT-001"
  • Role: "WebServer" or "DatabaseServer"
  • Application: "Frontend" or "Backend"

The Tagging Problem

The data disks (poc-vm1-data-disk, poc-vm2-data-disk) are intentionally created without tags to demonstrate the inheritance problem that this POC aims to solve.

Deployment and Validation

1. Deploy the POC Infrastructure

Use the automated deployment script:

./deploy-infrastructure.sh

This script will:

  • βœ… Check Azure and Pulumi prerequisites
  • βœ… Deploy the complete POC infrastructure
  • βœ… Display deployment summary with resource information
  • βœ… Provide next steps and useful commands

2. Validate the Tagging Problem

Run the validation script to see the tagging inheritance issue:

./validate-tagging-problem.sh

This script will:

  • πŸ“‹ List all resources in the resource group
  • 🏷️ Show VM tagging status (should be comprehensive)
  • πŸ’Ύ Show disk tagging status (should be missing tags)
  • πŸ“Š Use Azure Resource Graph for detailed analysis
  • πŸ“ˆ Provide compliance statistics

3. Validate Azure Policy Implementation

After deployment, validate that the Azure Policy implementation is working correctly:

./validate-policy-implementation.sh

This script will:

  • πŸ” Check that custom policy definitions are deployed
  • πŸ“‹ Verify policy initiative (policy set) is created
  • βœ… Confirm policy assignments are active at resource group scope
  • πŸ” Validate managed identity and role assignments
  • πŸ“Š Show current policy compliance status
  • 🏷️ Display current resource tagging state
  • πŸ“ˆ Provide policy enforcement summary and next steps

The validation will confirm:

  • βœ… Tag Inheritance Policy: Audits disks without inherited tags
  • βœ… Required Tags Policy: Enforces required tags on VMs
  • βœ… Policy Initiative: Comprehensive tagging governance
  • βœ… Policy Assignments: Active enforcement at resource group scope
  • βœ… Managed Identity: Proper permissions for policy execution

4. Expected Results

After deployment and validation, you should see:

  • βœ… VMs with comprehensive tags
  • ❌ Data disks without any tags (demonstrating the problem)
  • βœ… Azure Policies deployed and actively monitoring compliance
  • πŸ“Š Policy compliance reports showing untagged resources
  • πŸ” Clear demonstration of the tagging inheritance problem and governance solution

Development Workflow

1. Make Infrastructure Changes

Edit index.ts to modify your infrastructure:

import * as azure from "@pulumi/azure-native";

// Your infrastructure code here

2. Preview Changes

pulumi preview

3. Deploy Changes

pulumi up
# or use the deployment script
./deploy-infrastructure.sh

4. View Outputs

pulumi stack output

5. Validate Changes

# Validate the tagging inheritance problem
./validate-tagging-problem.sh

# Validate Azure Policy implementation
./validate-policy-implementation.sh

6. Apply Policy Remediation (if needed)

If you have policies with modify effect that need to fix existing non-compliant resources:

# Create remediation task for tag inheritance policy
./create-remediation-task.sh -p tag-inheritance-assignment -r <your-resource-group> -w

# Or use the resource group from your stack output
RESOURCE_GROUP=$(pulumi stack output resourceGroupName)
./create-remediation-task.sh -p tag-inheritance-assignment -r $RESOURCE_GROUP -w -v

7. Destroy Resources (when done)

pulumi destroy

Resource Discovery and Analysis

After deploying the POC infrastructure, use Azure Resource Graph to analyze tagging compliance and identify gaps.

1. Test KQL Queries

Before running the full analysis, test that the queries work correctly:

./test-queries.sh

This will validate all KQL queries and show sample results.

2. Run Comprehensive Analysis

Execute the full resource tagging analysis:

./analyze-resource-tagging.sh

This script will:

  • πŸ” Find VMs and their attached disks
  • 🏷️ Identify untagged disks with tagged parent VMs
  • πŸ“Š Analyze all POC resources and their tagging status
  • πŸ“‹ Generate timestamped reports in analysis-results/ directory
  • πŸ“ˆ Provide compliance statistics and recommendations

3. Review Analysis Results

The analysis generates several output files:

# View the summary report
cat analysis-results/summary-report_<timestamp>.md

# Check untagged data disks
cat analysis-results/untagged-data-disks_<timestamp>.json

# Review comprehensive analysis
cat analysis-results/comprehensive-analysis_<timestamp>.json

4. Available KQL Queries

The project includes several KQL queries in the queries/ directory:

  • find-vms-and-disks.kql: Discovers VMs and their attached disks
  • find-untagged-disks.kql: Identifies untagged disks with tagged parent VMs
  • find-untagged-data-disks.kql: Finds untagged data disks in POC environment
  • comprehensive-tagging-analysis.kql: Analyzes all POC resources and tagging status

5. Manual Query Execution

You can also run individual queries manually:

# Find untagged data disks
az graph query -q "$(cat queries/find-untagged-data-disks.kql)" --output table

# Get detailed JSON output
az graph query -q "$(cat queries/find-untagged-data-disks.kql)" --output json

# Analyze all POC resources
az graph query -q "$(cat queries/comprehensive-tagging-analysis.kql)" --output table

6. Understanding the Results

The analysis will typically show:

  • βœ… VMs: Properly tagged with 6 tags each
  • βœ… OS Disks: Inherit tags from VM during creation
  • ❌ Data Disks: Missing tags (demonstrating the inheritance problem)
  • βœ… Network Resources: Properly tagged

Azure Policy Implementation

The POC includes a comprehensive Azure Policy implementation to address tag inheritance and governance challenges.

Policy Components

The implementation includes:

  1. Tag Inheritance Policy (audit effect)

    • Identifies disks attached to VMs that don't have inherited tags
    • Audits resources for compliance reporting
    • Helps identify tagging gaps for manual remediation
  2. Required Tags Policy (deny effect)

    • Enforces that all VMs must have required tags
    • Prevents creation of non-compliant resources
    • Ensures consistent tagging from resource creation
  3. Policy Initiative (Policy Set)

    • Combines both policies into a comprehensive governance framework
    • Provides centralized management and assignment
    • Enables consistent policy enforcement across resources

Policy Validation

After deployment, validate the policy implementation:

./validate-policy-implementation.sh

Policy Monitoring

Monitor policy compliance through:

  • Azure Portal: Policy > Compliance dashboard
  • CLI Commands: az policy state list --resource-group <rg-name>
  • Compliance Reports: Generated by the validation script

Policy Effects

  • Audit Effect: Identifies non-compliant resources without blocking operations
  • Deny Effect: Prevents creation of non-compliant resources

Note: This POC does not implement automatic tag remediation (modify effect). The policies focus on identification and prevention rather than automatic correction.

Policy Remediation

When Azure Policies with modify effect are deployed, they don't automatically fix existing non-compliant resources. You need to create remediation tasks to apply the policy changes to existing resources.

Automated Remediation Script

Use the provided script to create remediation tasks:

# Basic usage - create remediation for tag inheritance policy
./create-remediation-task.sh -p tag-inheritance-assignment -r poc-rgxxx

# With custom name and wait for completion
./create-remediation-task.sh -p tag-inheritance-assignment -r poc-rgxxx -n my-remediation-task -w

# Verbose output with waiting
./create-remediation-task.sh --policy-assignment tag-inheritance-assignment --resource-group poc-rgxxx --wait --verbose

Script Features

The create-remediation-task.sh script provides:

  • βœ… Validation: Checks Azure CLI login, resource group, and policy assignment existence
  • πŸ” Pre-check: Identifies non-compliant resources before creating remediation
  • 🏷️ Auto-naming: Generates timestamped remediation names if not provided
  • ⏱️ Wait Option: Optionally waits for remediation completion (up to 5 minutes)
  • πŸ“Š Status Monitoring: Shows remediation progress and final status
  • 🎯 Flexible Options: Supports custom scopes, filters, and verbose output

Script Options

Option Description Required
-p, --policy-assignment Policy assignment name βœ… Yes
-r, --resource-group Resource group name βœ… Yes
-n, --name Custom remediation name ❌ No (auto-generated)
-s, --scope Custom scope for remediation ❌ No
-f, --filter Resource discovery filter ❌ No
-w, --wait Wait for completion ❌ No
-v, --verbose Verbose output ❌ No
-h, --help Show help message ❌ No

Manual Remediation Commands

You can also create remediation tasks manually:

# Create remediation task
az policy remediation create \
    --name "tag-inheritance-remediation-$(date +%Y%m%d-%H%M%S)" \
    --policy-assignment tag-inheritance-assignment \
    --resource-group poc-rgxxx

# Check remediation status
az policy remediation show \
    --name "your-remediation-name" \
    --resource-group poc-rgxxx

# List all remediation tasks
az policy remediation list --resource-group poc-rgxxx --output table

Understanding Remediation Results

After running remediation:

  1. Check Deployment Status: Look for successfulDeployments count
  2. Verify Resource Tags: Confirm tags have been applied to previously untagged resources
  3. Monitor Compliance: Use policy compliance reports to verify improvements

Alternative: Automated Tagging Solution

If the Azure Policy approach (policy + remediation) doesn't work for your environment, use the automated tagging script as an alternative:

# Test what would be changed (dry run)
./tag-inheritance-script.sh --subscription YOUR_SUBSCRIPTION_ID --dry-run

# Apply tag inheritance to untagged disks
./tag-inheritance-script.sh --subscription YOUR_SUBSCRIPTION_ID

This script directly applies VM tags to untagged disks without requiring Azure Policy. See docs/phase3-automated-tagging-solution.md for detailed documentation.

Next Steps for Production

For production implementation, consider:

  1. Expand Scope: Apply policies at subscription or management group level
  2. Add Remediation: Implement modify effect policies for automatic tag inheritance
  3. Custom Logic: Develop more sophisticated tag inheritance rules
  4. Monitoring: Set up alerts for policy compliance violations
  5. Exception Handling: Define exemptions for special cases
  6. Automated Remediation: Schedule regular remediation tasks for ongoing compliance
  7. Remediation Workflows: Integrate remediation into CI/CD pipelines or Azure Automation

README.md
Provided by Tidal [email protected]

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published