Skip to main content
Pulumi logo Pulumi logo
  1. Docs
  2. Reference
  3. Pre-built Policy Packs
  4. NIST
  5. Azure

NIST SP 800-53 - Azure

    This page lists all 158 policies in the NIST SP 800-53 pack for Azure, as published in nist-azure version 1.0.0.

    Policies by control

    AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.

    AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.

    AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.

    AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.

    AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.

    AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.

    AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.

    AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.

    AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.

    CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.

    CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.

    CM-3 Configuration Change Control — The organization determines the types of changes to the information system that are configuration-controlled.

    CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.

    CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.

    CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.

    IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).

    IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.

    RA-5 Vulnerability Monitoring and Scanning — The organization monitors and scans for vulnerabilities in the information system and hosted applications and remediates legitimate vulnerabilities.

    SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.

    SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.

    SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.

    SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.

    SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.

    SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.

    SI-4 Information System Monitoring — The organization monitors the information system to detect attacks and indicators of potential attacks.

    Policy details

    aad-custom-roles

    Severity: high · Enforcement: advisory

    Prevent Azure AD custom roles and Azure Native custom role definitions with broad permissions.

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Remove Broad Permissions from Custom Roles
    To pass this policy:
    • Replace wildcard (*) actions with specific permissions
    • Remove forbidden actions (Microsoft.Authorization/, Microsoft.Resources/)
    • Keep total actions under 50 (or configured limit)
    Fix for Azure Native Custom Roles
    new azure.authorization.RoleDefinition("custom-role", {
        roleName: "Storage Manager",
        roleType: "CustomRole",
        assignableScopes: [`/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`],
        permissions: [{
            actions: [
                "Microsoft.Storage/storageAccounts/read",
                "Microsoft.Storage/storageAccounts/write",
                "Microsoft.Storage/storageAccounts/listKeys/action",
            ], // Specific actions only, no wildcards
            notActions: [],
        }],
    });
    
    Fix for Azure AD Custom Roles
    new azuread.CustomDirectoryRole("custom-aad-role", {
        displayName: "User Support Specialist",
        enabled: true,
        permissions: [{
            allowedResourceActions: [
                "microsoft.directory/users/password/update",
                "microsoft.directory/users/usageLocation/update",
                "microsoft.directory/users/userPrincipalName/update",
            ], // Specific actions only, no wildcards
        }],
    });
    

    aad-direct-user-roles

    Severity: high · Enforcement: advisory

    Prevent Azure AD users from having direct role assignments.

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    Remediation
    Fix: Use Group-Based Role Assignments
    To pass this policy:
    • Assign roles to Azure AD groups, not individual users
    • Set principalType to “Group” instead of “User”
    // Create a security group
    const devGroup = new azuread.Group("dev-team", {
        displayName: "Development Team",
        securityEnabled: true,
    });
    
    // Assign role to the group (not to users directly)
    new azure.authorization.RoleAssignment("group-role", {
        principalId: devGroup.id,
        principalType: "Group", // Must be Group, not User
        roleDefinitionId: contributorRoleId,
        scope: resourceGroupScope,
    });
    
    // Add users as group members
    new azuread.GroupMember("dev-member", {
        groupObjectId: devGroup.id,
        memberObjectId: userObjectId,
    });
    

    aad-global-admin-no-permanent-access

    Severity: high · Enforcement: advisory

    Manage default global administrator accounts to prevent permanent privileged access.

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Remove Permanent Global Administrator Access
    To pass this policy:
    • Add conditions to Global Admin assignments (condition & conditionVersion properties)
    • Never assign Global Admin to Service Principals
    // BAD: Permanent Global Administrator assignment without conditions
    new azure.authorization.RoleAssignment("permanent-global-admin", {
        principalId: userId,
        principalType: "User",
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
        scope: "/",
    });
    
    // GOOD: Conditional assignment
    new azure.authorization.RoleAssignment("conditional-global-admin", {
        principalId: groupId,
        principalType: "Group", // Use groups, not individual users
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
        scope: "/subscriptions/${subscriptionId}", // Limit scope when possible
        condition: "@Resource[Microsoft.Authorization/roleAssignments:principalId] StringEquals '${groupId}'",
        conditionVersion: "2.0",
    });
    
    Use Azure Native PIM Resources (When Available)

    Configure time-bounded eligible role assignments:

    // Create PIM Role Eligibility Schedule
    new azure.authorization.RoleEligibilitySchedule("global-admin-eligible", {
        scope: "/subscriptions/${subscriptionId}",
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
        principalId: groupId,
        principalType: "Group",
        expirationDate: "2024-12-31T23:59:59Z", // Must have expiration
        startDate: "2024-01-01T00:00:00Z",
    });
    
    Use Azure AD Privileged Access Groups

    Configure privileged access through Azure AD groups with eligibility schedules:

    // Create a privileged access group
    const privilegedAdminGroup = new azuread.Group("privileged-admins", {
        displayName: "Privileged Global Administrators",
        securityEnabled: true,
    });
    
    // Create eligibility schedule for the group
    new azuread.PrivilegedAccessGroupEligibilitySchedule("admin-eligibility", {
        groupId: privilegedAdminGroup.objectId,
        principalId: userId,
        assignmentType: "member",
        duration: "PT8H", // 8-hour eligibility window
        justification: "Required for quarterly security audit",
        startDate: "2024-01-01T00:00:00Z",
        permanentAssignment: false, // Never permanent
    });
    
    Implement Break-Glass Accounts with Monitoring

    Create dedicated emergency access accounts with proper alerts:

    // Create a break-glass security group
    const breakGlassGroup = new azuread.Group("break-glass-admins", {
        displayName: "Emergency Break-Glass Administrators",
        securityEnabled: true,
    });
    
    // Assign Global Admin to break-glass group (permanent but monitored)
    new azure.authorization.RoleAssignment("break-glass-admin", {
        principalId: breakGlassGroup.objectId,
        principalType: "Group",
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
        scope: "/",
    });
    
    // Create activity log alert for break-glass usage
    new azure.insights.ActivityLogAlert("break-glass-usage-alert", {
        resourceGroupName: securityResourceGroup.name,
        location: "Global",
        enabled: true,
        condition: {
            allOf: [{
                field: "category",
                equals: "Administrative",
            }, {
                field: "caller",
                contains: breakGlassGroup.objectId.apply(id => id),
            }],
        },
        actions: [{
            actionGroupId: securityAlertActionGroup.id,
        }],
    });
    
    Use Least Privilege Alternatives

    Consider using more specific admin roles instead of Global Administrator:

    // Instead of Global Administrator, use specific roles
    const specificAdminRoles = {
        userAdmin: "fe930be7-5e62-47db-91af-98c3a49a38b1",
        securityAdmin: "194ae4cb-b126-40b2-bd5b-6091b380977d",
        cloudAppAdmin: "158c047a-c907-4556-b7ef-446551a6b5f7",
        conditionalAccessAdmin: "b1be1c3e-b65d-4f19-8427-f6fa0d97feb9",
    };
    
    // Assign only the specific role needed
    new azure.authorization.RoleAssignment("security-admin-limited", {
        principalId: securityTeamGroupId,
        principalType: "Group",
        roleDefinitionId: `/providers/Microsoft.Authorization/roleDefinitions/${specificAdminRoles.securityAdmin}`,
        scope: "/subscriptions/${subscriptionId}",
    });
    
    Service Principals Should Never Have Global Admin
    // BAD: Service Principal with Global Admin
    new azure.authorization.RoleAssignment("sp-global-admin", {
        principalId: servicePrincipalId,
        principalType: "ServicePrincipal",
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
        scope: "/",
    });
    
    // GOOD: Service Principal with specific, scoped permissions
    new azure.authorization.RoleAssignment("sp-contributor", {
        principalId: servicePrincipalId,
        principalType: "ServicePrincipal",
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", // Contributor
        scope: "/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}",
    });
    

    aad-role-assignments

    Severity: high · Enforcement: advisory

    Prevent Azure AD and Azure Native role assignments with excessive privileges.

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Remove Excessive Role Assignment Privileges
    • Avoid forbidden roles (Owner, User Access Administrator)
    • Don’t use overly broad scopes (root “/” or all subscriptions)
    • Assign roles to groups instead of individual users
    // GOOD: Specific role, scoped to resource group, assigned to group
    new azure.authorization.RoleAssignment("good-assignment", {
        principalId: securityGroupId,
        principalType: "Group",
        roleDefinitionId: "/subscriptions/${subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", // Contributor
        scope: `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`,
    });
    

    aad-role-no-wildcard-assignments

    Severity: high · Enforcement: advisory

    Restrict administrator privileges - no wildcard role assignments.

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Remove Wildcard or Overly Broad Role Assignments
    To pass this policy:
    • Avoid root “/” or “/subscriptions” scopes
    • Don’t use wildcards (*) or “all” in scopes
    • Scope assignments to resource groups or specific resources
    • Service Principals must have narrow scopes (resource-level)
    • Add conditions for subscription-level assignments
    // GOOD: Resource group scoped
    new azure.authorization.RoleAssignment("specific-scope", {
        principalId: groupId,
        principalType: "Group",
        roleDefinitionId: contributorRoleId,
        scope: `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`,
    });
    
    // GOOD: Subscription-level with conditions
    new azure.authorization.RoleAssignment("conditional-broad", {
        principalId: groupId,
        roleDefinitionId: readerRoleId,
        scope: `/subscriptions/${subscriptionId}`,
        condition: "@Resource[Microsoft.Storage/storageAccounts:name] StringStartsWith 'dev'",
        conditionVersion: "2.0",
    });
    

    activity-log-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensure Activity Log encryption is enabled for data protection.

    • AU-9 Protection of Audit Information — The information system protects audit information and audit tools from unauthorized access, modification, and deletion.
    Remediation
    Fix: Enable Activity Log Encryption

    Your Activity Log data needs encryption both at rest and in transit to protect audit trail integrity.

    Configure Storage Account with encryption for Activity Log destination:

    const logStorage = new azure.storage.StorageAccount("activityLogStorage", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "Standard_GRS" },
        kind: "StorageV2",
        enableHttpsTrafficOnly: true,  // Required: HTTPS-only for encryption in transit
        minimumTlsVersion: "TLS1_2",   // Required: Minimum TLS 1.2
        encryption: {
            services: {
                blob: {
                    enabled: true,  // Required: Blob encryption at rest
                    keyType: "Account",
                },
                file: {
                    enabled: true,
                },
            },
            keySource: "Microsoft.Storage",  // Or "Microsoft.Keyvault" for customer-managed keys
        },
    });
    

    For customer-managed keys, integrate with Key Vault:

    const logStorage = new azure.storage.StorageAccount("activityLogStorage", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "Standard_GRS" },
        kind: "StorageV2",
        enableHttpsTrafficOnly: true,
        minimumTlsVersion: "TLS1_2",
        encryption: {
            services: {
                blob: { enabled: true, keyType: "Account" },
            },
            keySource: "Microsoft.Keyvault",  // Use customer-managed keys
            keyVaultProperties: {
                keyName: encryptionKey.name,
                keyVaultUri: keyVault.properties.vaultUri,
            },
        },
    });
    

    Configure Activity Log diagnostic settings with encrypted destination:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
        name: "activity-log-encrypted",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,  // Log Analytics (encrypted by default)
        storageAccountId: logStorage.id,  // Encrypted Storage Account
        logs: [
            { category: "Administrative", enabled: true },
            { category: "Security", enabled: true },
        ],
    });
    

    Note: Encryption requirements per CIS Controls v8 IG1 4.6:

    • At rest: Storage accounts must have blob encryption enabled
    • In transit: Storage accounts must enforce HTTPS-only traffic with TLS 1.2+
    • Customer-managed keys: Optional but recommended for additional control

    Log Analytics workspaces use Azure-managed encryption by default.

    activity-log-file-integrity-enabled

    Severity: high · Enforcement: advisory

    Ensure Activity Log file integrity monitoring is enabled for security monitoring.

    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    Remediation
    Fix: Enable Activity Log File Integrity Monitoring

    Your Activity Log diagnostic settings need file integrity monitoring configured to detect tampering with audit logs.

    Configure Activity Log diagnostic settings with file integrity monitoring:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
        name: "activity-log-to-workspace",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,
        logs: [
            { category: "Administrative", enabled: true },
            { category: "Security", enabled: true },
            { category: "Alert", enabled: true },
            { category: "Policy", enabled: true },
        ],
    });
    

    Apply tags to the Log Analytics Workspace to indicate file integrity monitoring:

    const workspace = new azure.operationalinsights.Workspace("securityWorkspace", {
        // ... other properties
        tags: {
            FileIntegrity: "enabled",              // File integrity monitoring enabled
            HashValidation: "sha256",              // Hash-based integrity validation
            IntegrityAlerting: "enabled",          // Alerts on integrity violations
        },
    });
    

    For Storage Account destinations, apply tags to indicate immutable storage:

    const logStorage = new azure.storage.StorageAccount("logStorage", {
        // ... other properties
        tags: {
            ImmutableStorage: "enabled",
            WORMCompliance: "enabled",
            TamperProof: "enabled",
        },
    });
    

    Note: DiagnosticSetting resources do NOT support tags. Apply tags to the destination resources (Log Analytics Workspace or Storage Account) to indicate file integrity monitoring is configured per CIS Controls v8 IG1 4.6. Immutable storage prevents log tampering and ensures audit trail integrity.

    activity-log-monitor-integration

    Severity: medium · Enforcement: advisory

    Ensure Activity Log is integrated with advanced monitoring solutions for comprehensive log analysis.

    • AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.
    Remediation
    Fix: Configure Activity Log Advanced Monitor Integration

    Your Activity Log needs integration with advanced monitoring solutions for comprehensive log analysis and threat detection.

    Set up Activity Log diagnostic settings with Log Analytics workspace:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
        name: "activity-log-advanced-monitoring",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,  // Link to Log Analytics workspace
        eventHubAuthorizationRuleId: eventHubRule.id,  // Optional: for real-time processing
        logs: [
            { category: "Administrative", enabled: true },
            { category: "Security", enabled: true },
            { category: "ServiceHealth", enabled: true },
            { category: "Alert", enabled: true },
            { category: "Recommendation", enabled: true },
            { category: "Policy", enabled: true },
            { category: "Autoscale", enabled: true },
            { category: "ResourceHealth", enabled: true },
        ],
        metrics: [
            { category: "AllMetrics", enabled: true },
        ],
    });
    

    Configure Log Analytics workspace with advanced analytics tags:

    const workspace = new azure.operationalinsights.Workspace("securityWorkspace", {
        // ... other properties
        retentionInDays: 730,  // Advanced analytics requires longer retention
        tags: {
            AdvancedAnalytics: "enabled",
            KQLQueries: "enabled",
            Workbooks: "enabled",
            MachineLearning: "enabled",
            AnomalyDetection: "enabled",
        },
    });
    

    Create alert rules for proactive monitoring:

    const securityAlert = new azure.monitor.ActivityLogAlert("securityAlert", {
        // ... configure alerts for critical security events
        tags: {
            ActivityLogBased: "true",
            SecurityMonitoring: "enabled",
            ThreatDetection: "enabled",
        },
    });
    

    Note: DiagnosticSetting resources do NOT support tags. Apply tags to the destination resources (Log Analytics Workspace, Activity Log Alerts, etc.) to indicate monitoring capabilities. This enables sophisticated log analysis, correlation, and real-time threat detection per CIS Controls v8 IG3 3.14.

    activity-log-monitoring

    Severity: medium · Enforcement: advisory

    Ensure Activity Log monitoring is properly configured.

    • AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.
    Remediation
    Fix: Enable Activity Log Monitoring Integration

    Your Activity Log needs to send data to a monitoring solution for centralized audit trail visibility.

    Configure Activity Log diagnostic settings:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
        name: "activity-log-monitoring",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,  // Required: Log Analytics workspace
        storageAccountId: storageAccount.id,  // Optional: for long-term retention
        logs: [
            { category: "Administrative", enabled: true },
            { category: "Security", enabled: true },
            { category: "Alert", enabled: true },
            { category: "Policy", enabled: true },
        ],
        retentionPolicy: {
            enabled: true,
            days: 365,  // Minimum 365 days recommended
        },
    });
    

    Ensure a Log Analytics workspace exists:

    const workspace = new azure.operationalinsights.Workspace("monitoringWorkspace", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "PerGB2018" },
        retentionInDays: 365,
    });
    

    Note: Activity Log monitoring provides audit trail visibility and enables security analysis per CIS Controls v8 IG2 3.8. Include all critical log categories (Administrative, Security, Alert, Policy) for comprehensive monitoring.

    activity-log-multi-region-trail-enabled

    Severity: high · Enforcement: advisory

    Ensure Activity Log multi-region trail is enabled for resilience and compliance.

    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    Remediation
    Fix: Configure Activity Log Multi-Region Trail

    Your Activity Log needs to send data to destinations in multiple regions for disaster recovery and business continuity.

    Deploy Log Analytics workspaces in multiple regions:

    const workspaceEast = new azure.operationalinsights.Workspace("workspaceEast", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "PerGB2018" },
        retentionInDays: 365,
    });
    
    const workspaceWest = new azure.operationalinsights.Workspace("workspaceWest", {
        resourceGroupName: resourceGroup.name,
        location: "westus2",  // Geographically redundant region
        sku: { name: "PerGB2018" },
        retentionInDays: 365,
    });
    

    Configure Activity Log to send to primary workspace:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
        name: "activity-log-multi-region",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspaceEast.id,  // Primary region
        storageAccountId: storageWest.id,  // Secondary region for redundancy
        logs: [
            { category: "Administrative", enabled: true },
            { category: "Security", enabled: true },
            { category: "Alert", enabled: true },
            { category: "Policy", enabled: true },
        ],
    });
    

    Recommended region pairs:

    • East US + West US 2
    • East US 2 + Central US
    • North Europe + West Europe
    • Southeast Asia + East Asia

    Note: Multi-region configuration ensures audit logs remain available during regional outages per CIS Controls v8 IG1 4.6. Deploy Activity Log destinations in at least 2 geographically redundant regions.

    activity-log-security-trail-enabled

    Severity: high · Enforcement: advisory

    Ensure Activity Log security trail is enabled for security monitoring and compliance.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Activity Log Security Trail

    Your Activity Log needs to capture security events and administrative actions for compliance and security monitoring.

    Configure Activity Log diagnostic settings with security categories:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogSecurityTrail", {
        name: "activity-log-security-trail",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,  // Send to Log Analytics workspace
        storageAccountId: storageAccount.id,  // Optional: for archival
        logs: [
            { category: "Security", enabled: true },         // Required: Security events
            { category: "Administrative", enabled: true },   // Required: Admin actions
            { category: "Policy", enabled: true },           // Policy evaluation events
            { category: "Alert", enabled: true },            // Alert events
        ],
        retentionPolicy: {
            enabled: true,
            days: 365,  // Minimum 365 days for security trail
        },
    });
    

    Ensure at least one destination is configured:

    // Option 1: Log Analytics workspace (recommended)
    const workspace = new azure.operationalinsights.Workspace("securityWorkspace", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "PerGB2018" },
        retentionInDays: 365,
    });
    
    // Option 2: Storage Account for archival
    const storageAccount = new azure.storage.StorageAccount("securityLogs", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "Standard_GRS" },
        kind: "StorageV2",
    });
    
    // Option 3: Event Hub for real-time processing
    const eventHub = new azure.eventhub.EventHub("securityEvents", {
        // ... configure Event Hub
    });
    

    Note: Security trail captures security-relevant events including authentication, authorization, resource changes, and policy violations per CIS Controls v8 IG1 4.1. Both Security and Administrative categories are required for comprehensive audit trails.

    activity-log-storage-dataevents

    Severity: medium · Enforcement: advisory

    Ensure Activity Log captures Storage Account data events for comprehensive log analysis.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Storage Account Data Events Logging

    Your Storage Accounts need data plane diagnostic settings to capture data access events for comprehensive log analysis.

    Configure diagnostic settings for Storage Account blob service:

    const blobDiagnostic = new azure.monitor.DiagnosticSetting("blobDataEvents", {
        name: "blob-data-events",
        resourceUri: pulumi.interpolate`${storageAccount.id}/blobServices/default`,
        workspaceId: workspace.id,  // Send to Log Analytics
        logs: [
            { category: "StorageRead", enabled: true },
            { category: "StorageWrite", enabled: true },
            { category: "StorageDelete", enabled: true },
        ],
        metrics: [
            { category: "Transaction", enabled: true },
        ],
    });
    

    Tag your Storage Account to indicate data event logging:

    const storageAccount = new azure.storage.StorageAccount("myStorage", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        tags: {
            DataEventLogging: "enabled",
            StorageDataEvents: "enabled",
            AuditDataAccess: "enabled",
        },
    });
    

    Configure Activity Log to capture subscription-level storage events:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
        name: "activity-log-storage-events",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,
        logs: [
            { category: "Administrative", enabled: true },  // Captures storage account management operations
            { category: "Security", enabled: true },
        ],
        retentionPolicy: {
            enabled: true,
            days: 365,
        },
    });
    

    Optional: Configure Event Grid for real-time storage events:

    const eventSubscription = new azure.eventgrid.EventSubscription("storageEvents", {
        scope: storageAccount.id,
        destination: {
            endpointType: "eventhub",
            // ... configure destination
        },
        filter: {
            includedEventTypes: [
                "Microsoft.Storage.BlobCreated",
                "Microsoft.Storage.BlobDeleted",
            ],
        },
    });
    

    Note: Data plane logging captures individual blob read/write/delete operations. This provides comprehensive audit trails for data access monitoring per CIS Controls v8 IG3 3.14. Configure for blob, file, table, and queue services as needed.

    activity-log-trail-enabled

    Severity: high · Enforcement: advisory

    Collect audit logs from Activity Log trails.

    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    Remediation
    Fix: Enable Activity Log Trail Collection

    Your subscription needs Activity Log diagnostic settings configured to collect comprehensive audit trails.

    Configure Activity Log diagnostic settings at subscription level:

    const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogTrail", {
        name: "activity-log-audit-trail",
        resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
        workspaceId: workspace.id,  // Required: Log Analytics workspace
        storageAccountId: storageAccount.id,  // Optional: for long-term archival
        eventHubAuthorizationRuleId: eventHubRule.id,  // Optional: for real-time streaming
        logs: [
            { category: "Administrative", enabled: true },
            { category: "Security", enabled: true },
            { category: "Alert", enabled: true },
            { category: "Policy", enabled: true },
            { category: "Recommendation", enabled: true },
            { category: "ResourceHealth", enabled: true },
            { category: "ServiceHealth", enabled: true },
            { category: "Autoscale", enabled: true },
        ],
        metrics: [
            { category: "AllMetrics", enabled: true },
        ],
        retentionPolicy: {
            enabled: true,
            days: 365,  // Minimum 365 days recommended
        },
    });
    

    Create required destination resources:

    // Log Analytics workspace for analysis
    const workspace = new azure.operationalinsights.Workspace("auditWorkspace", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "PerGB2018" },
        retentionInDays: 365,
    });
    
    // Storage Account for archival (optional)
    const storageAccount = new azure.storage.StorageAccount("auditLogs", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        sku: { name: "Standard_GRS" },
        kind: "StorageV2",
    });
    

    Optional: Configure Activity Log alerts for critical events:

    const criticalAlert = new azure.monitor.ActivityLogAlert("criticalEvents", {
        resourceGroupName: resourceGroup.name,
        scopes: [pulumi.interpolate`/subscriptions/${subscriptionId}`],
        condition: {
            allOf: [
                { field: "category", equals: "Security" },
                { field: "level", equals: "Critical" },
            ],
        },
        actions: {
            actionGroups: [actionGroup.id],
        },
    });
    

    Note: Activity Log trails provide comprehensive audit logs for all subscription-level activities per CIS Controls v8 IG1 8.2. Enable all relevant categories and configure at least one destination (Log Analytics, Storage Account, or Event Hub).

    aks-auto-upgrade

    Severity: high · Enforcement: advisory

    Require AKS clusters to have auto-upgrade enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Auto-Upgrade for AKS Cluster
    const aksCluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
        dnsPrefix: "myaks",
        autoUpgradeProfile: {
            upgradeChannel: "stable",       // Set to 'stable', 'patch', or 'rapid'
            nodeOSUpgradeChannel: "NodeImage",  // Enable node OS auto-upgrade
        },
        // ... other config
    });
    

    aks-azure-ad-integration

    Severity: high · Enforcement: advisory

    Require AKS clusters to use Azure AD integration

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Enable AKS Azure AD Integration
    const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
        enableRBAC: true,  // Required for Azure AD
        aadProfile: {
            managed: true,  // Enable managed Azure AD integration
            enableAzureRBAC: true,  // Optional: Azure RBAC for Kubernetes
        },
        disableLocalAccounts: true,  // Disable local accounts for enhanced security
        // ... other config
    });
    

    aks-network-policies

    Severity: high · Enforcement: advisory

    Require AKS clusters to have network policies enabled

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Enable AKS Network Policies
    const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
        networkProfile: {
            networkPlugin: "azure",  // Azure CNI recommended
            networkPolicy: "calico",  // Enable network policy (calico, azure, or cilium)
        },
        // ... other config
    });
    

    aks-node-pools-vm-scale-sets

    Severity: high · Enforcement: advisory

    Require AKS node pools to use VM Scale Sets

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure AKS Node Pools to Use VM Scale Sets
    const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
        agentPoolProfiles: [{
            name: "nodepool1",
            vmSize: "Standard_DS2_v2",
            type: "VirtualMachineScaleSets",  // Use VM Scale Sets for availability
            // ... other config
        }],
        // ... other config
    });
    

    aks-private-clusters

    Severity: high · Enforcement: advisory

    Require AKS clusters to be private clusters

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure AKS as a Private Cluster
    const aksCluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
        apiServerAccessProfile: {
            enablePrivateCluster: true,  // Enable private cluster mode
            privateDNSZone: "system",  // Use system-managed private DNS zone
            enablePrivateClusterPublicFQDN: false,  // Disable public FQDN
        },
        // ... other config
    });
    

    aks-secret-encryption

    Severity: high · Enforcement: advisory

    Require AKS clusters to have secret encryption enabled

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Enable AKS Secret Encryption with Azure Key Vault
    const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
        addonProfiles: {
            azureKeyvaultSecretsProvider: {
                enabled: true,  // Enable Azure Key Vault Secrets Provider
                config: {
                    enableSecretRotation: "true",  // Enable secret rotation
                    rotationPollInterval: "2m",  // Set rotation interval
                },
            },
        },
        // ... other config
    });
    

    api-management-diagnostic-settings-exist

    Severity: medium · Enforcement: advisory

    Ensure API Management has diagnostic settings configured (existence check).

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Execution Logging for API Management

    Your API Management service needs advanced execution logging. Configure detailed logging with Log Analytics:

    const diagnostics = new azure.insights.DiagnosticSetting("apimExecutionLogs", {
        name: "apim-execution-diagnostics",
        resourceUri: apimService.id,
        workspaceId: logAnalyticsWorkspace.id,
        logs: [
            {
                category: "GatewayLogs",  // Request/response execution logs
                enabled: true,
                retentionPolicy: { enabled: true, days: 365 },
            },
            {
                category: "WebSocketConnectionLogs",  // WebSocket execution
                enabled: true,
                retentionPolicy: { enabled: true, days: 365 },
            },
        ],
        metrics: [{
            category: "AllMetrics",  // Performance metrics
            enabled: true,
        }],
    });
    

    Note: This policy checks that diagnostic settings exist. Use the ‘diagnostic-setting-configuration’ resource policy to validate the configuration details of diagnostic settings.

    api-management-tls

    Severity: high · Enforcement: advisory

    Require API Management to have secure TLS/SSL configuration

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure Secure TLS Settings
    const apiManagementService = new azurenative.apimanagement.ApiManagementService("my-api-mgmt", {
        customProperties: {
            "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10": "false",  // Disable TLS 1.0
            "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11": "false",  // Disable TLS 1.1
            "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10": "false",  // Disable backend TLS 1.0
            "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11": "false",  // Disable backend TLS 1.1
        },
        // ... other config
    });
    

    app-service-disable-ftp

    Severity: medium · Enforcement: advisory

    Require App Service to block insecure FTP access

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Disable FTP Access
    const webApp = new azurenative.web.WebApp("mywebapp", {
        siteConfig: {
            ftpsState: "Disabled",  // Disable FTP access (or use "FtpsOnly" for encrypted FTP)
        },
        // ... other config
    });
    

    app-service-https-only

    Severity: high · Enforcement: advisory

    Require App Service to enforce HTTPS only connections

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enforce HTTPS Only
    const webApp = new azurenative.web.WebApp("mywebapp", {
        httpsOnly: true,  // Redirect all HTTP traffic to HTTPS
        siteConfig: {
            minTlsVersion: "1.2",  // Set minimum TLS version
        },
        // ... other config
    });
    

    app-service-managed-updates

    Severity: medium · Enforcement: advisory

    Ensure App Service applications have managed updates enabled to maintain current software versions and security patches.

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Managed Updates for App Service

    Your App Service needs to be configured for managed updates to ensure security patches are applied automatically. Configure the required settings and tags:

    Step 1: Enable Always On and Update Settings
    const webApp = new azure.web.WebApp("myWebApp", {
        resourceGroupName: resourceGroup.name,
        serverFarmId: plan.id,
        siteConfig: {
            alwaysOn: true,  // Keep app loaded for consistent updates
            // Other site config settings
        },
        tags: {
            ManagedUpdates: "enabled",  // Document that managed updates are enabled
        },
    });
    
    const webApp = new azure.web.WebApp("myWebApp", {
        resourceGroupName: resourceGroup.name,
        serverFarmId: plan.id,
        siteConfig: {
            alwaysOn: true,
            autoSwapSlotName: "production",  // Auto-swap from staging after updates
        },
        tags: {
            ManagedUpdates: "enabled",
            UpdateStrategy: "staging-swap",
        },
    });
    
    // Create a staging slot for testing updates
    const stagingSlot = new azure.web.WebAppSlot("staging", {
        name: webApp.name,
        slot: "staging",
        resourceGroupName: resourceGroup.name,
        siteConfig: {
            alwaysOn: true,
        },
    });
    
    Accepted Tag Values

    The ManagedUpdates tag must be set to one of: enabled, true, yes, or 1.

    This ensures your App Service automatically receives security patches and platform updates while maintaining availability.

    application-gateway-has-health-probes

    Severity: medium · Enforcement: advisory

    Require Application Gateway to enable health probes

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Configure Health Probes
    const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
        probes: [{
            name: "health-probe",
            protocol: "Https",
            path: "/health",
            interval: 30,
            timeout: 30,
            unhealthyThreshold: 3,
            match: {
                statusCodes: ["200-399"],
            },
        }],
        backendHttpSettingsCollection: [{
            name: "backend-settings",
            probe: { id: healthProbe.id },  // Associate probe with backend settings
            // ... other config
        }],
        // ... other config
    });
    

    application-gateway-https-redirection

    Severity: high · Enforcement: advisory

    Ensure Application Gateway enforces HTTPS redirection to protect data in transit.

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure HTTP to HTTPS Redirection

    Your Application Gateway has HTTP listeners but doesn’t redirect traffic to HTTPS. All HTTP traffic should be automatically redirected to HTTPS for security.

    Configure HTTP to HTTPS Redirection
    const appGateway = new azure.network.ApplicationGateway("myGateway", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
    
        // ... other configuration ...
    
        // Define HTTP listener (port 80)
        httpListeners: [
            {
                name: "http-listener",
                protocol: "Http",
                frontendIPConfiguration: { id: frontendIP.id },
                frontendPort: { id: frontendPort80.id },
            },
            {
                name: "https-listener",
                protocol: "Https",
                frontendIPConfiguration: { id: frontendIP.id },
                frontendPort: { id: frontendPort443.id },
                sslCertificate: { id: sslCert.id },
            },
        ],
    
        // Create redirect configuration
        redirectConfigurations: [{
            name: "http-to-https-redirect",
            redirectType: "Permanent",  // HTTP 301
            targetListener: {
                id: pulumi.interpolate`${appGateway.id}/httpListeners/https-listener`,
            },
            includePath: true,
            includeQueryString: true,
        }],
    
        // Apply redirect to HTTP listener
        requestRoutingRules: [
            {
                name: "http-redirect-rule",
                ruleType: "Basic",
                priority: 100,
                httpListener: {
                    id: pulumi.interpolate`${appGateway.id}/httpListeners/http-listener`,
                },
                redirectConfiguration: {
                    id: pulumi.interpolate`${appGateway.id}/redirectConfigurations/http-to-https-redirect`,
                },
            },
            {
                name: "https-rule",
                ruleType: "Basic",
                priority: 110,
                httpListener: {
                    id: pulumi.interpolate`${appGateway.id}/httpListeners/https-listener`,
                },
                backendAddressPool: { id: backendPool.id },
                backendHttpSettings: { id: backendSettings.id },
            },
        ],
    });
    

    Note: Using “Permanent” (HTTP 301) redirect type tells browsers to always use HTTPS for future requests, improving security and performance.

    application-gateway-multi-az

    Severity: medium · Enforcement: advisory

    Require Application Gateway to be configured across multiple availability zones

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Deploy Across Multiple Availability Zones
    const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
        zones: ["1", "2", "3"],  // Deploy across at least 2 availability zones
        // ... other config
    });
    

    application-gateway-tls

    Severity: high · Enforcement: advisory

    Require Application Gateway to have secure TLS configuration

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure Secure TLS Policy
    const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
        sslPolicy: {
            policyType: "Predefined",
            policyName: "AppGwSslPolicy20220101",  // Use modern policy with TLS 1.2+
        },
        // ... other config
    });
    

    application-gateway-waf

    Severity: high · Enforcement: advisory

    Require Application Gateway to have Web Application Firewall enabled

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Enable Web Application Firewall
    const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
        sku: {
            name: "WAF_v2",
            tier: "WAF_v2",  // Use WAF-enabled SKU
        },
        webApplicationFirewallConfiguration: {
            enabled: true,  // Enable WAF protection
            firewallMode: "Prevention",  // Block threats
            ruleSetType: "OWASP",
            ruleSetVersion: "3.2",
        },
        // ... other config
    });
    

    azure-firewall-threat-intelligence

    Severity: high · Enforcement: advisory

    Require Azure Firewall to have threat intelligence enabled

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    • SI-4 Information System Monitoring — The organization monitors the information system to detect attacks and indicators of potential attacks.
    Remediation
    Fix: Enable Threat Intelligence on Azure Firewall
    const azureFirewall = new azurenative.network.AzureFirewall("my-firewall", {
        sku: { tier: "Standard" },
        threatIntelMode: "Deny",  // Set to "Deny" to block malicious traffic
        // ... other config
    });
    

    backup-instance-configuration

    Severity: medium · Enforcement: advisory

    Ensure backup instances are properly configured with backup policies and cross-region replication.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Backup Instance Properly

    Ensure your backup instance has proper configuration:

    const backupInstance = new azure.dataprotection.BackupInstance("disk-backup", {
        resourceGroupName: resourceGroup.name,
        vaultName: backupVault.name,
        properties: {
            dataSourceInfo: {
                resourceId: disk.id,
                resourceType: "Microsoft.Compute/disks",
            },
            policyInfo: {
                policyId: backupPolicy.id,
            },
        },
    });
    

    Note: Ensure the backup vault has appropriate storage settings and the backup policy defines proper retention.

    blob-service-lifecycle

    Severity: medium · Enforcement: advisory

    Require BlobServiceProperties to have versioning, change feed, and retention policies enabled

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Blob Service Lifecycle Policies
    const blobService = new azurenative.storage.BlobServiceProperties("default", {
        isVersioningEnabled: true,  // Enable versioning
        changeFeed: { enabled: true },  // Enable change feed
        deleteRetentionPolicy: { enabled: true, days: 7 },  // Enable delete retention
        // ... other config
    });
    

    cdn-distribution-logging-enabled

    Severity: medium · Enforcement: advisory

    Collect audit logs from CDN distributions for security monitoring.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable CDN Distribution Logging

    Your CDN needs audit logging configured. Enable diagnostic settings to collect access logs:

    const cdnProfile = new azure.cdn.Profile("myCdnProfile", {
        // ... other properties
        tags: {
            "LoggingEnabled": "enabled",
            "CDNLogging": "true",
        },
    });
    
    // Configure diagnostic settings for the CDN profile
    const cdnDiagnostics = new azure.insights.DiagnosticSetting("cdnDiagnostics", {
        name: "cdn-logging",
        resourceUri: cdnProfile.id,
        workspaceId: logAnalyticsWorkspace.id,  // Send logs to Log Analytics
        logs: [
            {
                category: "AzureCdnAccessLog",  // Access logs for standard CDN
                enabled: true,
                retentionPolicy: { enabled: true, days: 90 },
            },
        ],
    });
    

    For Azure Front Door (modern CDN):

    logs: [
        {
            category: "FrontDoorAccessLog",  // Access logs
            enabled: true,
        },
        {
            category: "FrontDoorHealthProbeLog",  // Health probe logs
            enabled: true,
        },
    ],
    

    container-instance-privileged-mode

    Severity: high · Enforcement: advisory

    Ensure Container Instances user for privileged mode check.

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Disable Privileged Mode for Container Instances

    Your container is configured to run in privileged mode. Remove privileged access and use proper security context:

    const containerGroup = new azure.containerinstance.ContainerGroup("myContainerGroup", {
        containers: [{
            name: "myContainer",
            image: "nginx:latest",
            resources: {
                requests: { cpu: 1, memoryInGB: 1.5 },
                limits: { cpu: 2, memoryInGB: 3 },  // Add resource limits
            },
            securityContext: {
                privileged: false,  // Never set to true
                runAsUser: 1000,  // Non-root user
                runAsGroup: 1000,  // Non-root group
                readOnlyRootFilesystem: true,  // Make root filesystem read-only
                capabilities: {
                    drop: ["ALL"],  // Drop all capabilities
                    // Only add specific needed capabilities
                },
            },
        }],
        osType: "Linux",
        ipAddress: { type: "Private" },  // Use private networking
    });
    

    Critical: Never set privileged: true or add dangerous capabilities like SYS_ADMIN, NET_ADMIN, or SYS_PTRACE.

    container-registry-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Container Registry to use customer-managed keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Container Registry Customer-Managed Keys
    const registry = new azurenative.containerregistry.Registry("my-registry", {
        sku: { name: "Premium" },  // Premium SKU required for customer-managed keys
        encryption: {
            status: "enabled",
            keyVaultProperties: {
                keyIdentifier: key.keyUri,  // Key Vault key URI
                identity: registryIdentity.id,  // User-assigned identity with Key Vault access
            },
        },
        // ... other config
    });
    

    cosmos-db-autoscaling-enabled

    Severity: medium · Enforcement: advisory

    Ensure Cosmos DB autoscaling is enabled.

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Enable Autoscaling for Cosmos DB

    Your Cosmos DB account needs autoscaling configured for optimal performance and cost management:

    const cosmosAccount = new azure.documentdb.DatabaseAccount("myCosmosDb", {
        // ... other properties
    });
    
    // For individual containers, enable autoscale throughput
    const container = new azure.documentdb.SqlResourceSqlContainer("myContainer", {
        // ... other properties
        options: {
            autoscaleSettings: {
                maxThroughput: 4000,  // Maximum RU/s - scales from 10% (400) to this value
            },
        },
    });
    

    Autoscaling helps manage costs by automatically adjusting throughput based on actual usage.

    cosmos-db-backup-policies

    Severity: medium · Enforcement: advisory

    Require Cosmos DB account to have backup policies configured

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Cosmos DB Backup Policies
    // Option 1: Continuous Backup (recommended)
    const cosmosDbContinuous = new azurenative.cosmosdb.DatabaseAccount("my-cosmosdb", {
        databaseAccountOfferType: "Standard",
        backupPolicy: {
            type: "Continuous",  // Enable continuous backup
            continuousModeProperties: {
                tier: "Continuous30Days",  // 30-day point-in-time restore
            },
        },
        // ... other config
    });
    
    // Option 2: Periodic Backup
    const cosmosDbPeriodic = new azurenative.cosmosdb.DatabaseAccount("my-cosmosdb", {
        databaseAccountOfferType: "Standard",
        backupPolicy: {
            type: "Periodic",  // Enable periodic backup
            periodicModeProperties: {
                backupIntervalInMinutes: 240,  // 4 hours
                backupRetentionIntervalInHours: 720,  // 30 days
            },
        },
        // ... other config
    });
    

    cosmos-db-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Cosmos DB to use customer-managed keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Keys for Cosmos DB
    const cosmosAccount = new azurenative.cosmosdb.DatabaseAccount("my-cosmos-account", {
        databaseAccountOfferType: "Standard",
        keyVaultKeyUri: key.keyUriWithVersion,  // Reference Key Vault key for encryption
        identity: {
            type: "UserAssigned",  // Use managed identity
            userAssignedIdentities: { [identity.id]: {} },
        },
        defaultIdentity: pulumi.interpolate`UserAssignedIdentity=${identity.id}`,
        // ... other config
    });
    

    cosmos-db-pitr-enabled

    Severity: medium · Enforcement: advisory

    Ensure Cosmos DB point-in-time recovery is enabled for data protection.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable Point-in-Time Recovery for Cosmos DB

    Your Cosmos DB account needs continuous backup for point-in-time recovery:

    const cosmosAccount = new azure.documentdb.DatabaseAccount("myCosmosDb", {
        // ... other properties
        backupPolicy: {
            type: "Continuous",  // Enable continuous backup for PITR
            continuousModeProperties: {
                tier: "Continuous7Days",  // or "Continuous30Days"
            },
        },
    });
    

    Note: Continuous backup allows restore to any point within the retention period (7 or 30 days).

    cosmos-db-private-endpoints

    Severity: high · Enforcement: advisory

    Require Cosmos DB account to have public network access disabled (indicating private endpoint usage)

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Cosmos DB with Private Endpoints
    const cosmosAccount = new azurenative.cosmosdb.DatabaseAccount("my-cosmos-account", {
        databaseAccountOfferType: "Standard",
        publicNetworkAccess: "Disabled",  // Disable public access to enforce private endpoints
        // ... other config
    });
    

    custom-image-validation

    Severity: medium · Enforcement: advisory

    Validate custom managed images meet governance and security requirements

    • CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.
    Remediation
    Fix: Add Required Governance Tags
    const customImage = new azurenative.compute.Image("my-custom-image", {
        tags: {
            "approved-by": "security-team@example.com",
            "creation-date": "2025-01-07",  // YYYY-MM-DD format
            "source-image": "Canonical:UbuntuServer:20.04-LTS",
            "vulnerability-scan-passed": "true",  // Must be 'true', 'yes', or 'passed'
            "hardening-applied": "true",  // Must be 'true', 'yes', or 'applied'
        },
        // ... other config
    });
    

    data-factory-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Data Factory to use customer-managed keys for encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Keys for Data Factory
    const factory = new azurenative.datafactory.Factory("my-data-factory", {
        encryption: {
            keyName: key.name,  // Reference Key Vault key
            vaultBaseUrl: pulumi.interpolate`https://${keyVault.name}.vault.azure.net/`,
            keyVersion: key.version,  // Optional: specify key version
        },
        // ... other config
    });
    

    defender-for-cloud-enabled

    Severity: high · Enforcement: advisory

    Ensure Microsoft Defender for Cloud is enabled for asset discovery and threat detection.

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    • SI-4 Information System Monitoring — The organization monitors the information system to detect attacks and indicators of potential attacks.
    Remediation
    Fix: Enable Microsoft Defender for Cloud

    Your resources need Microsoft Defender for Cloud enabled for threat detection:

    // Enable Advanced Threat Protection for a resource
    const atp = new azure.security.AdvancedThreatProtection("myResourceATP", {
        resourceId: storageAccount.id,  // or other resource
        isEnabled: true,  // Enable threat detection
    });
    
    // Tag your resource to indicate Defender is enabled
    tags: {
        "DefenderForCloud": "enabled",
        "AdvancedThreatProtection": "true",
        "SecurityMonitoring": "configured",
    }
    

    Enable Defender for specific resource types: Storage, SQL, Key Vault, Kubernetes, App Service, etc.

    diagnostic-setting-configuration

    Severity: medium · Enforcement: advisory

    Ensure diagnostic settings are properly configured with required destinations, log categories, and retention policies.

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    • AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.
    Remediation
    Fix: Configure Diagnostic Settings Properly

    Ensure your diagnostic settings include required destinations, log categories, and retention:

    const diagnostics = new azure.monitor.DiagnosticSetting("myDiagnostics", {
        resourceUri: resource.id,
        workspaceId: logAnalyticsWorkspace.id,  // Log Analytics
        storageAccountId: storageAccount.id,     // Storage for retention
        logs: [
            {
                category: "AuditLogs",
                enabled: true,
                retentionPolicy: { enabled: true, days: 365 },
            },
        ],
        metrics: [
            {
                category: "AllMetrics",
                enabled: true,
            },
        ],
    });
    

    Note: Configure appropriate log categories based on the resource type being monitored.

    dms-instance-public-access

    Severity: high · Enforcement: advisory

    Prevent public accessibility of Database Migration Service instances.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Public Access for Database Migration Service

    Your Database Migration Service allows public network access. Disable it and use VNet integration:

    const dmsService = new azure.datamigration.Service("myDMS", {
        // ... other properties
        publicNetworkAccess: "Disabled",  // Block public access
        virtualSubnetId: privateSubnet.id,  // Deploy in private subnet
        tags: {
            "PrivateEndpoint": "configured",
            "NetworkSecurityGroup": "associated",
        },
    });
    

    This ensures the DMS instance is only accessible from within your virtual network.

    event-hubs-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Event Hub namespace to use customer-managed keys for encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Keys for Event Hub Namespace
    const namespace = new azurenative.eventhub.Namespace("my-eventhub-namespace", {
        sku: {
            tier: "Premium",  // Customer-managed keys require Premium or Dedicated tier
        },
        encryption: {
            keySource: "Microsoft.KeyVault",  // Use Key Vault for customer-managed keys
            keyVaultProperties: [{
                keyName: "eventhub-encryption-key",
                keyVaultUri: keyVault.properties.vaultUri,
                identity: {
                    userAssignedIdentity: identity.id,
                },
            }],
        },
        // ... other config
    });
    

    event-hubs-retention

    Severity: medium · Enforcement: advisory

    Require Event Hubs to have proper retention policies configured

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    Remediation
    Fix: Configure Proper Event Hub Retention Policies
    const eventHub = new azurenative.eventhub.EventHub("my-eventhub", {
        namespaceName: namespace.name,
        messageRetentionInDays: 7,  // Set retention period (1-7 days for Standard, up to 90 days for Premium)
        // ... other config
    });
    

    flow-log-configuration

    Severity: medium · Enforcement: advisory

    Require proper Flow Log configuration for network monitoring

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    Remediation
    Fix: Configure Flow Log Settings
    const flowLog = new azurenative.network.FlowLog("my-flowlog", {
        retentionPolicy: {
            enabled: true,
            days: 90,  // Set retention period (minimum 30 days)
        },
        format: {
            version: 2,  // Use version 2 for enhanced data
        },
        // ... other config
    });
    

    front-door-tls

    Severity: high · Enforcement: advisory

    Require Front Door custom domains to use secure TLS configuration

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Configure Secure TLS Settings
    const customDomain = new azurenative.cdn.AFDCustomDomain("my-custom-domain", {
        tlsSettings: {
            minimumTlsVersion: "TLS12",  // Enforce minimum TLS 1.2
            certificateType: "ManagedCertificate",  // Use Azure-managed certificates
        },
        // ... other config
    });
    

    function-app-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Function Apps to use customer-managed keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Key Vault Reference Identity
    const functionApp = new azurenative.web.WebApp("myfunctionapp", {
        kind: "functionapp",
        identity: {
            type: "UserAssigned",  // Or "SystemAssigned"
            userAssignedIdentities: {
                [managedIdentity.id]: {},
            },
        },
        keyVaultReferenceIdentity: managedIdentity.id,  // Enable Key Vault integration
        // ... other config
    });
    

    function-public-access

    Severity: high · Enforcement: advisory

    Ensure Azure Functions restrict public access.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Restrict Public Access to Function App

    Your Function App allows unrestricted public access. Configure IP restrictions to limit access to specific IP ranges:

    Option 1: Configure IP Security Restrictions
    const functionApp = new azure.web.WebApp("myFunction", {
        kind: "functionapp",
        resourceGroupName: resourceGroup.name,
        serverFarmId: plan.id,
        siteConfig: {
            ipSecurityRestrictions: [
                {
                    ipAddress: "203.0.113.0/24",  // Your allowed IP range
                    action: "Allow",
                    priority: 100,
                    name: "AllowOfficeNetwork",
                },
                {
                    ipAddress: "198.51.100.10/32",  // Specific VPN IP
                    action: "Allow",
                    priority: 110,
                    name: "AllowVPN",
                },
            ],
            scmIpSecurityRestrictions: [  // Also restrict deployment access
                {
                    ipAddress: "203.0.113.0/24",
                    action: "Allow",
                    priority: 100,
                    name: "AllowOfficeDeployments",
                },
            ],
        },
        httpsOnly: true,  // Enforce HTTPS
    });
    
    Option 2: Disable Public Network Access (use with VNet integration)
    const functionApp = new azure.web.WebApp("myFunction", {
        kind: "functionapp",
        resourceGroupName: resourceGroup.name,
        serverFarmId: plan.id,
        publicNetworkAccess: "Disabled",  // Block all public access
        virtualNetworkSubnetId: subnet.id,  // Require VNet integration
        httpsOnly: true,
    });
    

    Do not use: ipAddress: "0.0.0.0/0" or leaving ipSecurityRestrictions empty, as these allow unrestricted public access.

    function-vnet-integration

    Severity: medium · Enforcement: advisory

    Ensure Azure Functions are integrated with Virtual Networks.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Enable VNet Integration for Function App

    Your Function App is not integrated with a Virtual Network. Configure VNet integration to isolate your function from the public internet:

    Step 1: Create a Dedicated Subnet for Function App
    const functionSubnet = new azure.network.Subnet("functionSubnet", {
        virtualNetworkName: vnet.name,
        resourceGroupName: resourceGroup.name,
        addressPrefix: "10.0.2.0/24",
        delegations: [{
            name: "delegation",
            serviceName: "Microsoft.Web/serverFarms",  // Required for Function Apps
        }],
    });
    
    Step 2: Configure Function App with VNet Integration
    const functionApp = new azure.web.WebApp("myFunction", {
        kind: "functionapp",
        resourceGroupName: resourceGroup.name,
        serverFarmId: plan.id,  // Must be Premium or Dedicated plan for VNet
        virtualNetworkSubnetId: functionSubnet.id,  // Connect to VNet subnet
        siteConfig: {
            vnetRouteAllEnabled: true,  // Route ALL outbound traffic through VNet
        },
    });
    
    Complete Example with Private Subnet
    const functionApp = new azure.web.WebApp("myFunction", {
        kind: "functionapp",
        resourceGroupName: resourceGroup.name,
        serverFarmId: premiumPlan.id,
        virtualNetworkSubnetId: functionSubnet.id,
        siteConfig: {
            vnetRouteAllEnabled: true,
            ipSecurityRestrictions: [],  // No public inbound access
        },
        publicNetworkAccess: "Disabled",  // Completely disable public access
    });
    

    Note: VNet integration requires an App Service Plan (Premium V2 or higher) or Elastic Premium plan. Consumption plans do not support VNet integration.

    hdinsight-cluster-public-access

    Severity: high · Enforcement: advisory

    Ensure HDInsight clusters restrict public access to master nodes.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Disable Public Access for HDInsight Cluster

    Your HDInsight cluster allows public access. Configure private link for secure connectivity:

    const hdinsightCluster = new azure.hdinsight.Cluster("myHDInsight", {
        // ... other properties
        computeProfile: {
            roles: [{
                name: "headnode",
                targetInstanceCount: 2,
                hardwareProfile: { vmSize: "Standard_D3_v2" },
                virtualNetworkProfile: {
                    id: vnet.id,
                    subnet: privateSubnet.id,
                },
            }],
        },
        networkProperties: {
            resourceProviderConnection: "Inbound",  // Disable outbound public access
            privateLink: "Enabled",  // Enable private link
        },
        tags: {
            "PublicAccess": "disabled",
            "PrivateLink": "enabled",
        },
    });
    

    hdinsight-kerberos-enabled

    Severity: high · Enforcement: advisory

    Ensure HDInsight Kerberos is enabled.

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Enable Kerberos Authentication for HDInsight

    Your HDInsight cluster needs Kerberos authentication for secure access:

    const hdinsightCluster = new azure.hdinsight.Cluster("myHDInsight", {
        // ... other properties
        securityProfile: {
            directoryType: "ActiveDirectory",  // Use Azure AD Domain Services
            domain: "yourdomain.com",
            domainUsername: "admin@yourdomain.com",
            domainUserPassword: domainPassword,
            ldapsUrls: ["ldaps://yourdomain.com:636"],
            clusterUsersGroupDNs: ["CN=HadoopUsers,OU=Groups,DC=yourdomain,DC=com"],
        },
        tags: {
            "KerberosEnabled": "true",
            "EnterpriseSecurityPackage": "enabled",
        },
    });
    

    Requirements: Azure AD Domain Services must be configured before enabling Kerberos.

    key-vault-access-policies

    Severity: high · Enforcement: advisory

    Require proper access controls for Key Vault access policies

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Specific Permissions Instead of “all”
    const keyVault = new azurenative.keyvault.Vault("my-keyvault", {
        properties: {
            sku: { name: "standard" },
            accessPolicies: [{
                tenantId: tenantId,
                objectId: servicePrincipalId,
                permissions: {
                    keys: ["get", "list", "encrypt", "decrypt"],  // Specific permissions instead of "all"
                    secrets: ["get", "list"],  // Specific permissions instead of "all"
                },
            }],
        },
        // ... other config
    });
    

    key-vault-key-configuration

    Severity: high · Enforcement: advisory

    Require proper Key Vault key creation and configuration

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure Key with Proper Type, Size, and Operations
    const key = new azurenative.keyvault.Key("my-key", {
        properties: {
            kty: "RSA",  // or "RSA-HSM" for hardware protection
            keySize: 2048,  // Minimum 2048 bits for RSA
            keyOps: ["encrypt", "decrypt"],  // Specify exact operations needed
            attributes: {
                exportable: false,
            },
        },
        // ... other config
    });
    

    key-vault-key-lifecycle

    Severity: high · Enforcement: advisory

    Require proper Key Vault key deletion and lifecycle management

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure Key Vault Key Lifecycle Attributes
    const key = new azurenative.keyvault.Key("my-key", {
        properties: {
            kty: "RSA",
            attributes: {
                exp: 1735689600,  // Set expiration date (Unix epoch timestamp)
                nbf: 1704067200,  // Set not-before date (Unix epoch timestamp)
            },
            // ... other config
        },
    });
    

    key-vault-key-not-scheduled-for-deletion

    Severity: high · Enforcement: advisory

    Ensure Key Vault keys are not scheduled for deletion and have proper lifecycle management.

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Protect Keys from Deletion in Key Vault

    Your Key Vault keys lack deletion protection. Enable soft delete and purge protection:

    const keyVault = new azure.keyvault.Vault("myVault", {
        // ... other properties
        properties: {
            enableSoftDelete: true,  // Enable soft delete (mandatory)
            softDeleteRetentionInDays: 90,  // Retain deleted items for 90 days
            enablePurgeProtection: true,  // Prevent permanent deletion during retention
            sku: { family: "A", name: "standard" },
        },
    });
    

    Important: Once enabled, purge protection cannot be disabled. Ensure this is intended for production vaults.

    key-vault-key-rotation

    Severity: high · Enforcement: advisory

    Require Key Vault keys to have rotation policies configured

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Configure Key Vault Key Rotation Policy
    const key = new azurenative.keyvault.Key("my-key", {
        properties: {
            kty: "RSA",
            rotationPolicy: {
                attributes: {
                    expiryTime: "P2Y",  // Set expiry time for key versions
                },
                lifetimeActions: [{
                    action: { type: "rotate" },
                    trigger: { timeAfterCreate: "P90D" },  // Rotate 90 days after creation
                }],
            },
            // ... other config
        },
    });
    

    key-vault-network-access

    Severity: high · Enforcement: advisory

    Require Key Vault to have network access controls configured

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Key Vault Network Access Controls
    const vault = new azurenative.keyvault.Vault("my-key-vault", {
        properties: {
            sku: { name: "standard" },
            networkAcls: {
                defaultAction: "Deny",  // Set default action to Deny
                bypass: "AzureServices",
                // ... other config
            },
            // ... other config
        },
    });
    

    key-vault-purge-protection

    Severity: high · Enforcement: advisory

    Require Key Vault to have purge protection enabled

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Enable Key Vault Purge Protection
    const vault = new azurenative.keyvault.Vault("my-key-vault", {
        properties: {
            sku: { name: "standard" },
            enablePurgeProtection: true,  // Enable purge protection
            // ... other config
        },
    });
    

    key-vault-soft-delete

    Severity: high · Enforcement: advisory

    Require Key Vault to have soft delete enabled with appropriate retention

    • SC-12 Cryptographic Key Establishment and Management — The organization establishes and manages cryptographic keys for required cryptography employed within the information system.
    Remediation
    Fix: Enable Key Vault Soft Delete
    const vault = new azurenative.keyvault.Vault("my-key-vault", {
        properties: {
            sku: { name: "standard" },
            enableSoftDelete: true,  // Enable soft delete
            softDeleteRetentionInDays: 90,  // Set retention period (minimum 90 days)
            // ... other config
        },
    });
    

    keyvault-rbac-least-privilege

    Severity: high · Enforcement: advisory

    Ensure Key Vaults using RBAC use appropriate Key Vault-specific roles instead of broad management roles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Enable RBAC Authorization on Key Vault
    const keyVault = new azurenative.keyvault.Vault("my-keyvault", {
        properties: {
            sku: { name: "standard" },
            enableRbacAuthorization: true,  // Enable RBAC for better access control
            accessPolicies: [],
        },
        // ... other config
    });
    

    load-balancer-cross-zone-enabled

    Severity: medium · Enforcement: advisory

    Ensure Load Balancer cross-zone load balancing is enabled.

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Enable Cross-Zone Load Balancing

    Your Load Balancer needs to be configured for cross-zone load balancing to ensure high availability across availability zones.

    Configure Zone-Redundant Load Balancer
    // Create zone-redundant public IP
    const publicIP = new azure.network.PublicIPAddress("myPublicIP", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        publicIPAllocationMethod: "Static",
        sku: {
            name: "Standard",  // Standard SKU required for zone redundancy
            tier: "Regional",
        },
        zones: ["1", "2", "3"],  // Deploy across all availability zones
    });
    
    // Create zone-redundant load balancer
    const loadBalancer = new azure.network.LoadBalancer("myLB", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
    
        sku: {
            name: "Standard",  // Standard SKU supports cross-zone balancing
            tier: "Regional",
        },
    
        frontendIPConfigurations: [{
            name: "frontend",
            publicIPAddress: { id: publicIP.id },
            zones: ["1", "2", "3"],  // Zone-redundant configuration
        }],
    
        // ... backend pools, rules, probes ...
    });
    
    Deploy Backend Resources Across Zones

    Ensure your backend resources (VMs, VMSS) are distributed across zones:

    const vmss = new azure.compute.VirtualMachineScaleSet("backend-vmss", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
    
        sku: {
            name: "Standard_D2s_v3",
            capacity: 3,
        },
    
        zones: ["1", "2", "3"],  // Distribute instances across zones
    
        // ... other VMSS configuration ...
    });
    
    Optimize Health Probes for Fast Failover
    const loadBalancer = new azure.network.LoadBalancer("myLB", {
        // ... other configuration ...
    
        probes: [{
            name: "health-probe",
            protocol: "Http",  // Note: Azure Load Balancer probes don't support HTTPS protocol
            port: 443,         // The probe connects to HTTPS port, but protocol detection is TCP/HTTP only
            requestPath: "/health",
            intervalInSeconds: 5,  // Fast probe interval
            numberOfProbes: 2,     // Quick failover (5s * 2 = 10s total)
        }],
    });
    

    Note: Standard SKU Load Balancers are zone-redundant by default when the frontend IP is zone-redundant. Basic SKU does not support availability zones - upgrade to Standard.

    load-balancer-deletion-protection

    Severity: high · Enforcement: advisory

    Ensure critical Load Balancers have resource locks to prevent accidental deletion.

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Apply Resource Lock to Load Balancer

    Your Load Balancer needs deletion protection. Apply a resource lock to prevent accidental deletion:

    const lock = new azure.authorization.ManagementLockAtResourceLevel("lb-delete-lock", {
        level: "CanNotDelete",
        lockName: "lb-delete-lock",
        notes: "Prevents accidental deletion of production load balancer",
        resourceGroupName: resourceGroup.name,
        resourceName: loadBalancer.name,
        resourceProviderNamespace: "Microsoft.Network",
        resourceType: "loadBalancers",
    });
    
    Lock Levels
    • CanNotDelete: Users can read and modify the resource, but cannot delete it
    • ReadOnly: Users can read the resource, but cannot modify or delete it

    load-balancer-health-probes

    Severity: medium · Enforcement: advisory

    Require Load Balancer to enable health probes

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Configure Load Balancer Health Probes
    const loadBalancer = new azurenative.network.LoadBalancer("my-load-balancer", {
        sku: { name: "Standard" },
        probes: [{
            name: "http-health-probe",
            properties: {
                protocol: "Http",
                port: 80,
                requestPath: "/health",  // Configure health check endpoint
            },
        }],
        loadBalancingRules: [{
            name: "http-rule",
            properties: {
                probe: { id: probeId },  // Associate probe with rule
                // ... other config
            },
        }],
    });
    

    load-balancer-https-listeners

    Severity: high · Enforcement: advisory

    Ensure Load Balancer uses TLS/HTTPS listeners only for secure communication.

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Use HTTPS Listeners Instead of HTTP

    Your Load Balancer has HTTP listeners without HTTPS alternatives. All traffic should be encrypted in transit using HTTPS.

    Replace HTTP Listeners with HTTPS
    const loadBalancer = new azure.network.LoadBalancer("myLB", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: { name: "Standard" },
    
        frontendIPConfigurations: [{
            name: "frontend",
            publicIPAddress: { id: publicIP.id },
        }],
    
        loadBalancingRules: [
            // Remove HTTP rule (port 80)
            // {
            //     name: "http-rule",
            //     frontendPort: 80,
            //     backendPort: 80,
            //     protocol: "Tcp",
            // },
    
            // Add HTTPS rule (port 443)
            {
                name: "https-rule",
                frontendPort: 443,
                backendPort: 443,
                protocol: "Tcp",
                frontendIPConfiguration: {
                    id: pulumi.interpolate`${loadBalancer.id}/frontendIPConfigurations/frontend`,
                },
                backendAddressPool: {
                    id: pulumi.interpolate`${loadBalancer.id}/backendAddressPools/backend`,
                },
                probe: {
                    id: pulumi.interpolate`${loadBalancer.id}/probes/https-probe`,
                },
            },
        ],
    
        probes: [{
            name: "https-probe",
            protocol: "Http",  // Note: Azure Load Balancer probes don't support HTTPS protocol
            port: 443,         // The probe connects to HTTPS port, but protocol detection is TCP/HTTP only
            requestPath: "/health",
            intervalInSeconds: 15,
            numberOfProbes: 2,
        }],
    });
    

    Note: For Azure Application Gateway (Layer 7), you can also implement HTTP to HTTPS redirection. For Azure Load Balancer (Layer 4), you should only expose HTTPS ports.

    load-balancer-logging

    Severity: medium · Enforcement: advisory

    Ensure Load Balancer has logging enabled for comprehensive security and performance analysis.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Diagnostic Logging for Load Balancer

    Your Load Balancer doesn’t have diagnostic settings configured. Enable logging to monitor load balancer health, performance, and security events.

    Configure Diagnostic Settings
    const logAnalyticsWorkspace = new azure.operationalinsights.Workspace("logs", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: { name: "PerGB2018" },
    });
    
    const loadBalancer = new azure.network.LoadBalancer("myLB", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        // ... other load balancer configuration
    });
    
    const diagnosticSetting = new azure.monitor.DiagnosticSetting("lb-diagnostics", {
        resourceUri: loadBalancer.id,
        workspaceId: logAnalyticsWorkspace.id,
    
        logs: [
            {
                category: "LoadBalancerAlertEvent",
                enabled: true,
                retentionPolicy: {
                    enabled: true,
                    days: 365,
                },
            },
            {
                category: "LoadBalancerProbeHealthStatus",
                enabled: true,
                retentionPolicy: {
                    enabled: true,
                    days: 365,
                },
            },
        ],
    
        metrics: [{
            category: "AllMetrics",
            enabled: true,
            retentionPolicy: {
                enabled: true,
                days: 365,
            },
        }],
    });
    
    Send Logs to Multiple Destinations

    For comprehensive monitoring, send logs to multiple destinations:

    const diagnosticSetting = new azure.monitor.DiagnosticSetting("lb-diagnostics", {
        resourceUri: loadBalancer.id,
        workspaceId: logAnalyticsWorkspace.id,
        storageAccountId: storageAccount.id,  // Long-term storage
        eventHubAuthorizationRuleId: eventHubRule.id,  // Real-time processing
    
        logs: [
            { category: "LoadBalancerAlertEvent", enabled: true },
            { category: "LoadBalancerProbeHealthStatus", enabled: true },
        ],
        metrics: [{ category: "AllMetrics", enabled: true }],
    });
    

    Note: Standard Load Balancers support diagnostic logging. Basic SKU load balancers have limited logging capabilities - consider upgrading to Standard.

    load-balancer-multi-az

    Severity: medium · Enforcement: advisory

    Require Load Balancer to be configured across multiple availability zones

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure Load Balancer for Multiple Availability Zones
    const loadBalancer = new azurenative.network.LoadBalancer("my-lb", {
        sku: {
            name: "Standard",  // Standard SKU required for zone redundancy
        },
        frontendIPConfigurations: [{
            zones: ["1", "2", "3"],  // Deploy across multiple zones
            // ... other config
        }],
    });
    

    log-analytics-retention

    Severity: medium · Enforcement: advisory

    Require Log Analytics workspace to have appropriate retention policies

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    Remediation
    Fix: Configure Log Analytics Workspace Retention Policy
    const workspace = new azurenative.operationalinsights.Workspace("my-workspace", {
        sku: {
            name: "PerGB2018",
        },
        retentionInDays: 90,  // Set to meet compliance requirements (minimum 90 days)
        // ... other config
    });
    

    managed-disk-attached-encryption-enabled

    Severity: high · Enforcement: advisory

    Ensure Managed Disks are encrypted when attached to virtual machines.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Encryption for Attached Managed Disk

    Your attached managed disk lacks encryption configuration. Enable encryption using one of these methods:

    1. Enable platform-managed key encryption (basic):
    const disk = new azure.compute.Disk("my-disk", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Empty",
        },
        diskSizeGB: 128,
        encryption: {
            type: "EncryptionAtRestWithPlatformKey",
        },
    });
    
    1. Enable customer-managed key encryption (recommended for sensitive data):
    // First, create a disk encryption set
    const diskEncryptionSet = new azure.compute.DiskEncryptionSet("my-des", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        identity: {
            type: "SystemAssigned",
        },
        encryptionType: "EncryptionAtRestWithCustomerKey",
        activeKey: {
            sourceVault: {
                id: keyVault.id,
            },
            keyUrl: key.keyUriWithVersion,
        },
    });
    
    // Then, use it with your disk
    const disk = new azure.compute.Disk("my-disk", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Empty",
        },
        diskSizeGB: 128,
        encryption: {
            type: "EncryptionAtRestWithCustomerKey",
            diskEncryptionSetId: diskEncryptionSet.id,
        },
    });
    
    1. Enable double encryption with platform and customer keys (maximum security):
    const disk = new azure.compute.Disk("my-disk", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Empty",
        },
        diskSizeGB: 128,
        encryption: {
            type: "EncryptionAtRestWithPlatformAndCustomerKeys",
            diskEncryptionSetId: diskEncryptionSet.id,
        },
    });
    

    managed-disk-backup-protection-exists

    Severity: medium · Enforcement: advisory

    Ensure Managed Disks have backup protection (existence check).

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Backup Protection for Managed Disks

    Your managed disk lacks proper backup configuration. Enable automated backups using Azure Backup or snapshot policies.

    Note: This policy checks that backup protection exists. Use the ‘backup-instance-configuration’ and ‘snapshot-configuration’ resource policies to validate backup configuration details.

    Option 1: Use Azure Backup with Backup Vault
    const backupVault = new azure.dataprotection.BackupVault("backup-vault", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        properties: {
            storageSettings: [{
                datastoreType: "VaultStore",
                type: "LocallyRedundant",
            }],
        },
    });
    
    const backupPolicy = new azure.dataprotection.BackupPolicy("disk-backup-policy", {
        resourceGroupName: resourceGroup.name,
        vaultName: backupVault.name,
        properties: {
            policyRules: [
                // Configure backup schedule and retention
            ],
        },
    });
    
    // Associate disk with backup instance
    const backupInstance = new azure.dataprotection.BackupInstance("disk-backup", {
        resourceGroupName: resourceGroup.name,
        vaultName: backupVault.name,
        properties: {
            dataSourceInfo: {
                resourceId: disk.id,
            },
            policyInfo: {
                policyId: backupPolicy.id,
            },
        },
    });
    
    Option 2: Create Manual Snapshots
    const snapshot = new azure.compute.Snapshot("disk-snapshot", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Copy",
            sourceResourceId: disk.id,
        },
    });
    

    managed-disk-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require managed disks to use customer-managed encryption keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Keys for Managed Disk
    const disk = new azurenative.compute.Disk("my-disk", {
        sku: { name: "Premium_LRS" },
        diskSizeGB: 128,
        creationData: { createOption: "Empty" },
        encryption: {
            type: "EncryptionAtRestWithCustomerKey",  // Use customer-managed key
            diskEncryptionSetId: diskEncryptionSet.id,  // Reference to Disk Encryption Set
        },
        // ... other config
    });
    

    managed-disk-snapshot-restrict-network-access

    Severity: high · Enforcement: advisory

    Ensure Managed Disk snapshots use restrictive network access policies (not AllowAll).

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Use Restrictive Network Access Policy on Managed Disk Snapshot

    Your snapshot has network access policy set to ‘AllowAll’. Use a more restrictive policy to limit access:

    For private endpoint access:

    const diskAccess = new azure.compute.DiskAccess("my-disk-access", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
    });
    
    const snapshot = new azure.compute.Snapshot("my-snapshot", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Copy",
            sourceResourceId: disk.id,
        },
        networkAccessPolicy: "AllowPrivate",
        diskAccessId: diskAccess.id,
    });
    

    For maximum security, deny all network access:

    const snapshot = new azure.compute.Snapshot("my-snapshot", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Copy",
            sourceResourceId: disk.id,
        },
        networkAccessPolicy: "DenyAll",
    });
    

    managed-disk-snapshot-restrict-public-access

    Severity: high · Enforcement: advisory

    Ensure Managed Disk snapshots do not allow public network access.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Public Network Access on Managed Disk Snapshot

    Your snapshot allows public network access. Disable public access to prevent unauthorized restore operations:

    const snapshot = new azure.compute.Snapshot("my-snapshot", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Copy",
            sourceResourceId: disk.id,
        },
        publicNetworkAccess: "Disabled",
        networkAccessPolicy: "AllowPrivate",
    });
    

    For maximum security, deny all network access:

    const snapshot = new azure.compute.Snapshot("my-snapshot", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Copy",
            sourceResourceId: disk.id,
        },
        publicNetworkAccess: "Disabled",
        networkAccessPolicy: "DenyAll",
    });
    

    managed-disk-unused

    Severity: medium · Enforcement: advisory

    Ensure Managed Disks are not unused to maintain proper asset inventory.

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Attach or Delete Unused Managed Disk

    Your managed disk is not attached to any VM. Take one of these actions:

    1. Attach the disk to a VM as a data disk:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        storageProfile: {
            dataDisks: [{
                lun: 0,
                createOption: "Attach",
                managedDisk: {
                    id: disk.id,
                },
            }],
        },
    });
    
    1. If the disk is truly unused, delete it to reduce costs and maintain clean asset inventory.

    ml-compute-instance-cmk-configured

    Severity: high · Enforcement: advisory

    Ensure Machine Learning compute instances use customer-managed keys for disk encryption.

    • AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.
    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Enable Customer-Managed Keys for ML Compute Instance

    Your ML compute instance needs disk encryption with customer-managed keys:

    // First configure the ML Workspace with CMK
    const mlWorkspace = new azure.machinelearningservices.Workspace("myWorkspace", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
        encryption: {
            status: "Enabled",
            keyVaultProperties: {
                keyIdentifier: encryptionKey.id,
                keyVaultArmId: keyVault.id,
            },
        },
        sku: { name: "Basic" },
    });
    
    // Compute instance inherits encryption from workspace
    const mlCompute = new azure.machinelearningservices.Compute("myMLCompute", {
        workspaceName: mlWorkspace.name,
        computeType: "ComputeInstance",
        properties: {
            vmSize: "Standard_DS3_v2",
            subnet: { id: privateSubnet.id },
            sshSettings: { sshPublicAccess: "Disabled" },
        },
    });
    

    Note: Compute instances inherit encryption settings from the parent workspace configuration.

    ml-compute-internet-access

    Severity: high · Enforcement: advisory

    Ensure Machine Learning compute instances do not have direct internet access.

    • AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Internet Access for ML Compute

    Your ML compute instance has direct internet access. Deploy in a private subnet:

    const mlCompute = new azure.machinelearningservices.Compute("myMLCompute", {
        // ... other properties
        properties: {
            computeType: "AmlCompute",  // or "ComputeInstance"
            properties: {
                vmSize: "Standard_DS3_v2",
                vmPriority: "Dedicated",
                subnet: { id: privateSubnet.id },  // Deploy in VNet
                enableNodePublicIp: false,  // Disable public IP on nodes
                isolationMode: "UserDefined",  // Enhanced network isolation
            },
        },
        tags: {
            "PublicAccess": "disabled",
            "VNetIntegration": "enabled",
            "PrivateEndpoint": "configured",
        },
    });
    

    Ensure your VNet has appropriate NSG rules and private endpoints for required services.

    ml-workspace-cmk-configured

    Severity: high · Enforcement: advisory

    Ensure Machine Learning workspaces use customer-managed keys for encryption at rest.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Keys for ML Workspace

    Your Machine Learning workspace needs customer-managed key encryption:

    const mlWorkspace = new azure.machinelearningservices.Workspace("myMLWorkspace", {
        resourceGroupName: resourceGroup.name,
        workspaceName: "my-ml-workspace",
        location: "eastus",
        encryption: {
            status: "Enabled",
            keyVaultProperties: {
                keyVaultArmId: keyVault.id,
                keyIdentifier: "https://myvault.vault.azure.net/keys/mykey/version",
            },
        },
        hbiWorkspace: true,  // High Business Impact for sensitive data
        // Note: Tags removed - tag-based validation is not enforced by this policy
    });
    

    Note: Associated resources (storage, App Insights, Container Registry) should also use CMK.

    mysql-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require MySQL flexible servers to use customer-managed keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable MySQL Customer-Managed Keys
    const mysqlServer = new azurenative.dbformysql.Server("my-mysql-server", {
        sku: {
            tier: "GeneralPurpose",
        },
        dataEncryption: {
            type: "AzureKeyVault",  // Use customer-managed keys from Key Vault
            primaryKeyURI: key.keyUri,
            primaryUserAssignedIdentityId: identity.id,
        },
        // ... other config
    });
    

    mysql-private-endpoints

    Severity: high · Enforcement: advisory

    Require MySQL databases to use private endpoints

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure MySQL with Private Endpoints
    const mysqlServer = new azurenative.dbformysql.Server("my-mysql-server", {
        sku: {
            tier: "GeneralPurpose",
        },
        network: {
            publicNetworkAccess: "Disabled",  // Disable public network access
        },
        // ... other config
    });
    

    mysql-ssl-enforcement

    Severity: high · Enforcement: advisory

    Require MySQL databases to have SSL enforcement enabled

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable MySQL SSL Enforcement
    const requireSecureTransport = new azurenative.dbformysql.Configuration("require-secure-transport", {
        serverName: mysqlServer.name,
        configurationName: "require_secure_transport",
        value: "ON",  // Require SSL/TLS for all connections
        // ... other config
    });
    

    network-interface-no-public-ip

    Severity: critical · Enforcement: advisory

    Require Network Interfaces to have no public IP address associations

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Remove Public IP Address from Network Interface
    const nic = new azurenative.network.NetworkInterface("my-nic", {
        ipConfigurations: [{
            privateIPAllocationMethod: "Dynamic",
            // Do NOT include publicIPAddress property
            // ... other config
        }],
    });
    

    no-unrestricted-route-to-internet-gateway

    Severity: high · Enforcement: advisory

    Ensure route tables do not contain unrestricted routes to internet gateways for security monitoring.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Remove Unrestricted Internet Routes

    Your Route Table contains unrestricted routes to the internet (0.0.0.0/0). This violates network segmentation best practices.

    Option 1: Remove the Internet Route

    If direct internet access isn’t required, remove the route:

    const routeTable = new azure.network.RouteTable("myRouteTable", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        routes: [
            // Remove or comment out routes with 0.0.0.0/0 destination
            // {
            //     name: "internet-route",
            //     addressPrefix: "0.0.0.0/0",
            //     nextHopType: "Internet",
            // },
        ],
    });
    
    Option 2: Route Through Network Virtual Appliance

    If internet access is needed, route traffic through a firewall or NVA:

    const routeTable = new azure.network.RouteTable("myRouteTable", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        routes: [
            {
                name: "internet-via-firewall",
                addressPrefix: "0.0.0.0/0",
                nextHopType: "VirtualAppliance",
                nextHopIpAddress: "10.0.1.4",  // IP of your firewall/NVA
            },
        ],
        tags: {
            MonitoringEnabled: "true",
            SecurityApproved: "true",
        },
    });
    

    nsg-disallow-public-internet-ingress

    Severity: high · Enforcement: advisory

    Require Network Security Groups to disallow public internet ingress

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Remove Public Internet Ingress from Network Security Group
    const nsg = new azurenative.network.NetworkSecurityGroup("secure-nsg", {
        securityRules: [
            {
                protocol: "Tcp",
                sourceAddressPrefix: "203.0.113.0/24",  // Use specific IP ranges, not 0.0.0.0/0
                access: "Allow",
                direction: "Inbound",
                // ... other config
            },
        ],
    });
    

    nsg-http-restriction

    Severity: high · Enforcement: advisory

    Require Network Security Groups to disallow inbound HTTP traffic

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Restrict Inbound HTTP Traffic in Network Security Group
    const nsg = new azurenative.network.NetworkSecurityGroup("my-nsg", {
        securityRules: [
            {
                protocol: "Tcp",
                destinationPortRange: "80",
                access: "Deny",  // Deny HTTP traffic
                direction: "Inbound",
                // ... other config
            },
            {
                protocol: "Tcp",
                destinationPortRange: "443",
                access: "Allow",  // Allow HTTPS instead
                direction: "Inbound",
                // ... other config
            },
        ],
    });
    

    nsg-restrict-ingress-ssh-all

    Severity: high · Enforcement: advisory

    Restrict SSH access from all IPs in network security groups.

    • AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Restrict SSH Access to Specific IP Ranges

    Your Network Security Group allows SSH access from all IP addresses (0.0.0.0/0, *, or “Any”). Update the security rule to allow SSH only from specific trusted IP ranges:

    const nsg = new azure.network.NetworkSecurityGroup("myNSG", {
        securityRules: [
            {
                name: "AllowSSHFromOffice",
                priority: 100,
                direction: "Inbound",
                access: "Allow",
                protocol: "Tcp",
                sourceAddressPrefix: "203.0.113.0/24",  // Your office IP range
                sourcePortRange: "*",
                destinationAddressPrefix: "*",
                destinationPortRange: "22",
            },
        ],
    });
    

    For multiple allowed IP ranges, use sourceAddressPrefixes:

    sourceAddressPrefixes: [
        "203.0.113.0/24",    // Office network
        "198.51.100.10/32",  // VPN gateway
    ],
    

    Do not use: 0.0.0.0/0, *, Any, or Internet as the source address prefix, as these allow SSH access from anywhere on the internet.

    nsg-ssh-rdp-restriction

    Severity: high · Enforcement: advisory

    Require Network Security Groups to restrict SSH and RDP access

    • AC-17 Remote Access — The organization establishes and documents usage restrictions, configuration/connection requirements, and implementation guidance for each type of remote access allowed.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Restrict SSH and RDP Access in Network Security Group
    const nsg = new azurenative.network.NetworkSecurityGroup("secure-nsg", {
        securityRules: [
            {
                protocol: "Tcp",
                destinationPortRange: "22",
                sourceAddressPrefix: "10.0.255.0/24",  // Restrict to Bastion subnet, not 0.0.0.0/0
                access: "Allow",
                direction: "Inbound",
                // ... other config
            },
        ],
    });
    

    nsg-strict-rules

    Severity: high · Enforcement: advisory

    Require strict Network Security Group rules with explicit allow/deny configuration

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Strict Network Security Group Rules
    const nsg = new azurenative.network.NetworkSecurityGroup("strict-nsg", {
        securityRules: [
            {
                protocol: "Tcp",
                sourceAddressPrefix: "10.0.0.0/16",  // Use specific IP ranges, not * or 0.0.0.0/0
                destinationAddressPrefix: "10.0.1.0/24",  // Use specific destinations
                access: "Allow",
                direction: "Inbound",
                // ... other config
            },
        ],
    });
    

    postgresql-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require PostgreSQL flexible servers to use customer-managed keys

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Keys for PostgreSQL Flexible Server
    const server = new azurenative.dbforpostgresql.Server("my-postgres-server", {
        sku: {
            tier: "GeneralPurpose",
        },
        dataEncryption: {
            type: "AzureKeyVault",  // Use customer-managed keys from Key Vault
            primaryKeyUri: key.keyUriWithVersion,
            primaryUserAssignedIdentityId: identity.id,
        },
        // ... other config
    });
    

    postgresql-private-endpoints

    Severity: high · Enforcement: advisory

    Require PostgreSQL databases to use private endpoints

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure PostgreSQL with Private Endpoints
    const server = new azurenative.dbforpostgresql.Server("my-postgres-server", {
        sku: {
            tier: "GeneralPurpose",
        },
        network: {
            publicNetworkAccess: "Disabled",  // Disable public network access
        },
        // ... other config
    });
    

    postgresql-ssl-enforcement

    Severity: high · Enforcement: advisory

    Require PostgreSQL databases to have SSL enforcement enabled

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable SSL Enforcement for PostgreSQL
    const requireSecureTransport = new azurenative.dbforpostgresql.Configuration("require-secure-transport", {
        serverName: server.name,
        configurationName: "require_secure_transport",
        value: "ON",  // Require SSL/TLS for all connections
        // ... other config
    });
    

    prohibit-hardcoded-secrets

    Severity: critical · Enforcement: advisory

    Prohibit hardcoded secrets in code and configuration

    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Remove Hardcoded Secrets

    Remove hardcoded secrets from resource configuration.

    Example Violations

    Web App with hardcoded application settings:

    const webApp = new azurenative.web.WebApp("my-app", {
        siteConfig: {
            appSettings: [
                {
                    name: "DATABASE_PASSWORD",
                    value: "mySecretPassword123",  // Hardcoded secret
                },
                {
                    name: "API_KEY",
                    value: "sk_live_abc123def456789",  // Hardcoded secret
                },
            ],
        },
    });
    

    Container Group with hardcoded environment variables:

    const containerGroup = new azurenative.containerinstance.ContainerGroup("my-container", {
        containers: [{
            name: "app",
            environmentVariables: [
                {
                    name: "DATABASE_PASSWORD",
                    value: "mySecretPassword123",  // Hardcoded secret
                },
                {
                    name: "API_TOKEN",
                    value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",  // Hardcoded JWT token
                },
            ],
        }],
    });
    

    Web App with hardcoded connection string:

    const webApp = new azurenative.web.WebApp("my-app", {
        siteConfig: {
            connectionStrings: [{
                name: "DefaultConnection",
                connectionString: "Server=myserver;Database=mydb;User=admin;Password=hardcodedPassword123",
            }],
        },
    });
    

    rbac-least-privilege

    Severity: critical · Enforcement: advisory

    Enforce least privilege access control by prohibiting overly broad RBAC role assignments

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Specific Least-Privilege Roles
    const roleAssignment = new azurenative.authorization.RoleAssignment("my-assignment", {
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",  // Reader role instead of Owner/Contributor
        principalId: servicePrincipalId,
        scope: "/subscriptions/{sub-id}/resourceGroups/my-rg",  // Scope to resource group instead of subscription
    });
    

    redis-cache-non-ssl-port

    Severity: high · Enforcement: advisory

    Require Redis Cache to disable non-SSL port access

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Disable Non-SSL Port
    const redisCache = new azurenative.redis.Redis("my-redis-cache", {
        enableNonSslPort: false,  // Disable non-SSL port to enforce encrypted connections
        minimumTlsVersion: "1.2",  // Enforce minimum TLS 1.2
        // ... other config
    });
    

    redis-cache-private-endpoints

    Severity: high · Enforcement: advisory

    Require Redis Cache to use private endpoints

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Private Network Access
    const redisCache = new azurenative.redis.Redis("my-redis-cache", {
        sku: {
            name: "Premium",  // Premium SKU required for private endpoints
            family: "P",
        },
        publicNetworkAccess: "Disabled",  // Disable public access
        subnetId: subnet.id,  // Deploy in subnet for network isolation
        minimumTlsVersion: "1.2",
        // ... other config
    });
    

    resources-change-tracking-tags

    Severity: low · Enforcement: advisory

    Require all Azure resources to have proper tagging for change tracking

    • CM-3 Configuration Change Control — The organization determines the types of changes to the information system that are configuration-controlled.
    Remediation
    Fix: Add Change Tracking Tags to Resources
    const storageAccount = new azurenative.storage.StorageAccount("app-storage", {
        sku: {
            name: "Standard_LRS",
        },
        tags: {
            "last-modified": "2025-10-07",  // ISO 8601 date format (YYYY-MM-DD)
            "modified-by": "jane.doe@company.com",
            "change-reason": "Added storage account for new application deployment",
        },
        // ... other config
    });
    

    resources-environment-tags

    Severity: low · Enforcement: advisory

    Require all resources to have environment tags

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Add Environment Tag
    const resource = new azurenative.storage.StorageAccount("my-storage", {
        tags: {
            environment: "prod",  // Use "dev", "test", "staging", or "prod"
        },
        // ... other config
    });
    

    search-service-encrypted-at-rest

    Severity: high · Enforcement: advisory

    Ensure Search Services use encryption at rest with customer-managed keys for data protection.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Customer-Managed Key Encryption for Search Service

    Your Search Service needs encryption at rest with customer-managed keys:

    const searchService = new azure.search.Service("mySearch", {
        // ... other properties
        sku: { name: "Standard" },  // Standard tier or higher required for CMK
        encryptionWithCmk: {
            enforcement: "Enabled",  // Enforce CMK encryption
        },
    });
    
    // Note: Configure Key Vault key and grant Search Service managed identity access
    

    Important: Free and Basic SKUs don’t support customer-managed keys.

    search-service-logs-monitor

    Severity: medium · Enforcement: advisory

    Ensure Search Service sends logs to monitoring solutions for comprehensive log analysis.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable Logging for Search Service

    Your Search Service needs diagnostic logging configured:

    const diagnostics = new azure.insights.DiagnosticSetting("searchDiagnostics", {
        name: "search-logging",
        resourceUri: searchService.id,
        workspaceId: logAnalyticsWorkspace.id,
        logs: [
            {
                category: "OperationLogs",  // Search operations
                enabled: true,
                retentionPolicy: { enabled: true, days: 365 },
            },
            {
                category: "SearchSlowLogs",  // Slow query logs
                enabled: true,
                retentionPolicy: { enabled: true, days: 365 },
            },
        ],
        metrics: [{
            category: "AllMetrics",
            enabled: true,
        }],
    });
    

    Add tags to track logging configuration:

    tags: {
        "LoggingEnabled": "true",
        "LogAnalytics": logAnalyticsWorkspace.id,
    }
    

    search-service-vnet-only

    Severity: medium · Enforcement: advisory

    Ensure Search Service is in VNet only.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Restrict Search Service to VNet Only

    Your Search Service allows public access. Disable it and use private endpoints:

    const searchService = new azure.search.Service("mySearch", {
        // ... other properties
        sku: { name: "Standard" },  // Basic tier or higher required
        publicNetworkAccess: "disabled",  // Disable public access
        networkRuleSet: {
            bypass: "None",  // No bypass for Azure services
        },
        tags: {
            "PublicAccess": "disabled",
            "PrivateEndpoint": "configured",
            "VNetIntegration": "enabled",
        },
    });
    
    // Create private endpoint for the search service
    const privateEndpoint = new azure.network.PrivateEndpoint("searchPE", {
        // ... private endpoint configuration
        privateLinkServiceConnections: [{
            name: "search-connection",
            privateLinkServiceId: searchService.id,
            groupIds: ["searchService"],
        }],
    });
    

    security-center-enabled

    Severity: high · Enforcement: advisory

    Ensure Security Center is enabled for vulnerability management.

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    • RA-5 Vulnerability Monitoring and Scanning — The organization monitors and scans for vulnerabilities in the information system and hosted applications and remediates legitimate vulnerabilities.
    Remediation
    Fix: Enable Azure Security Center

    Your subscription needs Azure Security Center configured for vulnerability management:

    // Enable Security Center pricing for services
    const vmPricing = new azure.security.Pricing("vmPricing", {
        pricingName: "VirtualMachines",
        pricingTier: "Standard",  // or "Free" for basic protection
    });
    
    const storagePricing = new azure.security.Pricing("storagePricing", {
        pricingName: "StorageAccounts",
        pricingTier: "Standard",
    });
    
    // Configure security contacts
    const securityContact = new azure.security.SecurityContact("securityContact", {
        securityContactName: "default1",
        emails: "security@example.com",
        notificationsByRole: {
            state: "On",  // Enable email notifications
            roles: ["Owner"],  // Notify subscription admins
        },
    });
    
    // Enable auto-provisioning of security agents
    const autoProvisioning = new azure.security.AutoProvisioningSetting("autoProvision", {
        settingName: "default",
        autoProvision: "On",  // Automatically deploy agents
    });
    

    service-bus-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Service Bus namespace to use customer-managed keys for encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Service Bus Customer-Managed Keys
    const namespace = new azurenative.servicebus.Namespace("my-namespace", {
        sku: {
            name: "Premium",  // Premium tier required for customer-managed keys
            tier: "Premium",
        },
        encryption: {
            keySource: "Microsoft.KeyVault",  // Use Azure Key Vault for encryption keys
            keyVaultProperties: [{
                keyName: key.name,
                keyVaultUri: keyVault.properties.vaultUri,
                identity: {
                    userAssignedIdentity: identity.id,
                },
            }],
        },
        // ... other config
    });
    

    service-bus-dead-letter-queue

    Severity: medium · Enforcement: advisory

    Validate Service Bus queues have proper dead letter queue configuration

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure Service Bus Queue Dead Letter Settings
    const queue = new azurenative.servicebus.Queue("my-queue", {
        maxDeliveryCount: 10,  // Maximum delivery attempts before dead lettering
        deadLetteringOnMessageExpiration: true,  // Enable dead lettering when messages expire
        // ... other config
    });
    

    snapshot-configuration

    Severity: medium · Enforcement: advisory

    Ensure snapshots are properly configured for backup and recovery purposes.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Snapshot Properly

    Ensure your snapshot is properly configured:

    const snapshot = new azure.compute.Snapshot("disk-snapshot", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        creationData: {
            createOption: "Copy",
            sourceResourceId: disk.id,
        },
        encryption: {
            type: "EncryptionAtRestWithPlatformKey",
        },
        incremental: true,  // Use incremental snapshots for efficiency
    });
    

    Note: For automated snapshots, consider using snapshot policies or Azure Backup instead of manual snapshots.

    sql-database-backup-retention

    Severity: medium · Enforcement: advisory

    Require Azure SQL Database to have backup retention configured with redundant storage

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable SQL Database Backup Retention with Redundant Storage
    const database = new azurenative.sql.Database("my-database", {
        sku: {
            name: "S0",
            tier: "Standard",
        },
        requestedBackupStorageRedundancy: "Geo",  // Use geo-redundant backup storage
        // ... other config
    });
    

    sql-database-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Azure SQL databases to use customer-managed keys for transparent data encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable SQL Database Customer-Managed Keys for TDE
    const encryptionProtector = new azurenative.sql.EncryptionProtector("tde-protector", {
        serverKeyType: "AzureKeyVault",  // Use customer-managed key from Azure Key Vault
        serverKeyName: serverKey.name,
        autoRotationEnabled: true,  // Enable auto-rotation when key version changes
        // ... other config
    });
    

    sql-database-high-availability

    Severity: medium · Enforcement: advisory

    Require Azure SQL Database to have high availability configuration

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Enable SQL Database High Availability
    const database = new azurenative.sql.Database("my-database", {
        sku: {
            name: "P1",
            tier: "Premium",
        },
        zoneRedundant: true,  // Enable zone redundancy for high availability
        // ... other config
    });
    

    sql-database-least-privilege

    Severity: high · Enforcement: advisory

    Ensure SQL databases use appropriate SQL-specific roles instead of broad management roles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use SQL DB Contributor Instead of Broad Roles
    const sqlAssignment = new azurenative.authorization.RoleAssignment("sql-access", {
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/9b7fa17d-e63e-47b0-bb0a-15c516ac86ec",  // SQL DB Contributor
        principalId: appServicePrincipalId,
        scope: "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Sql/servers/myserver/databases/mydb",
        // ... other config
    });
    

    sql-database-tde-enabled-check

    Severity: high · Enforcement: advisory

    Require Azure SQL databases to enable transparent data encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Transparent Data Encryption
    const tde = new azurenative.sql.TransparentDataEncryption("tde", {
        resourceGroupName: resourceGroup.name,
        serverName: sqlServer.name,
        databaseName: database.name,
        state: "Enabled",  // Enable transparent data encryption
    });
    

    sql-server-audit-logging

    Severity: medium · Enforcement: advisory

    Require Azure SQL Server to have audit logging enabled

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable SQL Server Audit Logging
    const auditPolicy = new azurenative.sql.ServerBlobAuditingPolicy("audit-policy", {
        state: "Enabled",  // Enable audit logging
        storageEndpoint: storageEndpoint,
        retentionDays: 90,  // Retain audit logs for 90 days
        // ... other config
    });
    

    sql-server-azure-ad-authentication

    Severity: high · Enforcement: advisory

    Require Azure SQL Server to have Azure AD administrators configured

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Configure Azure AD Authentication for SQL Server
    const sqlServer = new azurenative.sql.Server("my-sql-server", {
        administrators: {
            administratorType: "ActiveDirectory",
            login: "admin@contoso.com",  // Azure AD admin user or group name
            sid: "00000000-0000-0000-0000-000000000000",  // Azure AD object ID
            tenantId: "00000000-0000-0000-0000-000000000000",
            principalType: "User",
        },
        // ... other config
    });
    

    sql-server-disable-public-access

    Severity: critical · Enforcement: advisory

    Require Azure SQL Server to disable public network access

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable SQL Server Public Network Access
    const sqlServer = new azurenative.sql.Server("my-sql-server", {
        publicNetworkAccess: "Disabled",  // Disable public network access
        // ... other config
    });
    

    sql-server-encrypted-connections

    Severity: high · Enforcement: advisory

    Require Azure SQL Server to have encrypted connections with minimum TLS 1.2

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable SQL Server Encrypted Connections
    const sqlServer = new azurenative.sql.Server("my-sql-server", {
        minimalTlsVersion: "1.2",  // Enforce TLS 1.2 or higher for encrypted connections
        // ... other config
    });
    

    sql-server-restrict-outbound-access

    Severity: high · Enforcement: advisory

    Require Azure SQL servers to restrict outbound network access to prevent data exfiltration

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Restrict Outbound Network Access
    const sqlServer = new azurenative.sql.Server("my-sql-server", {
        restrictOutboundNetworkAccess: "Enabled",  // Restrict outbound access
        // ... other config
    });
    

    storage-account-files-encryption

    Severity: high · Enforcement: advisory

    Require Files to have encryption enabled

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Azure Files Encryption
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        encryption: {
            services: {
                file: { enabled: true },  // Enable Azure Files encryption
            },
        },
        // ... other config
    });
    

    storage-account-firewall

    Severity: high · Enforcement: advisory

    Require Storage Accounts to have firewall rules configured

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Configure Storage Account Firewall Rules
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        networkRuleSet: {
            defaultAction: "Deny",  // Deny by default
            ipRules: [{ value: "203.0.113.0/24" }],  // Allow specific IPs
            virtualNetworkRules: [{ id: subnet.id }],  // Allow specific subnets
        },
        // ... other config
    });
    

    storage-account-geo-replication

    Severity: medium · Enforcement: advisory

    Require Storage Accounts to have geo-replication enabled for business continuity

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable Geo-Replication
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_GRS" },  // Use geo-replicated SKU for redundancy
        kind: "StorageV2",
        // ... other config
    });
    

    storage-account-https-only

    Severity: high · Enforcement: advisory

    Require Storage Accounts to enforce HTTPS-only traffic

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enable HTTPS-Only Traffic
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        enableHttpsTrafficOnly: true,  // Enforce HTTPS-only traffic
        // ... other config
    });
    

    storage-account-infrastructure-encryption

    Severity: medium · Enforcement: advisory

    Require Storage Accounts to enable infrastructure encryption for double encryption at rest

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Enable Infrastructure Encryption
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        encryption: {
            keySource: "Microsoft.Storage",
            requireInfrastructureEncryption: true,  // Enable double encryption at rest
        },
        // ... other config
    });
    

    storage-account-least-privilege

    Severity: high · Enforcement: advisory

    Ensure storage accounts use appropriate storage-specific roles instead of broad management roles

    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Use Storage Data Roles Instead of Management Roles
    const blobAssignment = new azurenative.authorization.RoleAssignment("blob-access", {
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",  // Storage Blob Data Contributor
        principalId: appPrincipalId,
        scope: storageAccount.id,
        // ... other config
    });
    

    storage-account-minimum-tls

    Severity: high · Enforcement: advisory

    Require Storage Accounts to enforce a minimum TLS version for data in transit

    • SC-8 Transmission Confidentiality and Integrity — The information system protects the confidentiality and integrity of transmitted information.
    Remediation
    Fix: Enforce Minimum TLS Version
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        minimumTlsVersion: "TLS1_2",  // Require TLS 1.2 or higher
        // ... other config
    });
    

    storage-account-policy-grantee

    Severity: high · Enforcement: advisory

    Ensure Storage Account policy grantee check.

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    • AC-6 Least Privilege — The organization employs the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) which are necessary to accomplish assigned tasks.
    Remediation
    Fix: Implement Group-Based Access Control

    Your storage account has too many direct user access grants or lacks proper access control documentation.

    Solution 1: Use Azure AD groups instead of direct user assignments:

    // Create or use existing Azure AD group
    const storageUsersGroup = new azuread.Group("storageUsers", {
        displayName: "Storage Users",
        securityEnabled: true,
    });
    
    // Assign role to group instead of individual users
    const roleAssignment = new azure.authorization.RoleAssignment("groupAccess", {
        resourceGroupName: resourceGroup.name,
        scope: storageAccount.id,
        principalId: storageUsersGroup.objectId,
        principalType: "Group",
        roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",  // Storage Blob Data Reader
    });
    

    Solution 2: Document access justification with tags:

    const storageAccount = new azure.storage.StorageAccount("myStorage", {
        resourceGroupName: resourceGroup.name,
        accountName: "mystorageaccount",
        tags: {
            AccessJustification: "Approved by Security Team - Ticket #12345",
            LastReviewed: "2024-01-15",
            LeastPrivilege: "enabled",
        },
        // ... other properties
    });
    

    Best Practices:

    • Prefer group-based access over direct user assignments
    • Use service principals or managed identities for applications
    • Document and review privileged access grants regularly
    • Implement least privilege principles

    storage-account-public-access

    Severity: critical · Enforcement: advisory

    Require Storage Accounts to disable public blob access

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Public Blob Access
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        allowBlobPublicAccess: false,  // Disable public blob access
        // ... other config
    });
    

    storage-account-public-network-access

    Severity: critical · Enforcement: advisory

    Require Storage Accounts to disable public network access

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Public Network Access
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: {
            name: "Standard_LRS",
        },
        kind: "StorageV2",
        publicNetworkAccess: "Disabled",  // Disable public network access
        // ... other config
    });
    

    storage-account-replication-enabled

    Severity: medium · Enforcement: advisory

    Ensure Storage Account replication is enabled for data availability and disaster recovery.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Storage Replication for Data Resilience

    Your storage account is using inadequate replication that doesn’t meet the minimum requirements for data availability.

    Solution: Use a SKU with appropriate replication:

    const storageAccount = new azure.storage.StorageAccount("myStorage", {
        resourceGroupName: resourceGroup.name,
        accountName: "mystorageaccount",
        sku: {
            name: "Standard_GRS",  // Geo-redundant storage (or RAGRS/GZRS/RAGZRS)
        },
        // ... other properties
    });
    

    Replication Types (in order of redundancy level):

    • Standard_LRS - Locally redundant (3 copies in one datacenter)
    • Standard_ZRS - Zone redundant (3 copies across availability zones)
    • Standard_GRS - Geo-redundant (6 copies across two regions)
    • Standard_RAGRS - Read-access geo-redundant (GRS + read access to secondary)
    • Standard_GZRS - Geo-zone-redundant (combines ZRS and GRS)
    • Standard_RAGZRS - Read-access geo-zone-redundant (GZRS + read access)

    For critical data, use geo-redundant options (GRS, RAGRS, GZRS, or RAGZRS) to protect against regional disasters.

    storage-account-shared-key-access

    Severity: high · Enforcement: advisory

    Require Storage Accounts to disable shared key access in favor of Azure AD authentication

    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Disable Shared Key Access
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        allowSharedKeyAccess: false,  // Require Azure AD authentication
        // ... other config
    });
    

    Shared key access defaults to enabled in Azure, so it must be explicitly set to false.

    storage-account-uses-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Storage Accounts to use customer-managed keys for encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Customer-Managed Keys
    const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
        encryption: {
            keySource: "Microsoft.Keyvault",  // Use customer-managed keys
            keyVaultProperties: {
                keyName: "my-encryption-key",
                keyVaultUri: "https://my-keyvault.vault.azure.net/",
            },
        },
        // ... other config
    });
    

    storage-account-versioning-enabled

    Severity: medium · Enforcement: advisory

    Perform automated backups for Storage Accounts with versioning.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Enable Blob Versioning for Data Protection

    Your storage account lacks blob versioning, which is critical for backup and recovery.

    Note: Blob versioning is configured via the Blob Service, not the Storage Account resource directly.

    Solution: Enable blob versioning using the BlobServiceProperties resource:

    const storageAccount = new azure.storage.StorageAccount("myStorage", {
        resourceGroupName: resourceGroup.name,
        accountName: "mystorageaccount",
        // ... other properties
    });
    
    // Enable blob versioning
    const blobService = new azure.storage.BlobServiceProperties("blobService", {
        resourceGroupName: resourceGroup.name,
        accountName: storageAccount.name,
        isVersioningEnabled: true,          // Enable versioning
        deleteRetentionPolicy: {
            enabled: true,
            days: 7,                         // Soft delete retention
        },
    });
    

    Lifecycle Management: Add lifecycle policies to manage storage costs:

    const managementPolicy = new azure.storage.ManagementPolicy("lifecycle", {
        resourceGroupName: resourceGroup.name,
        accountName: storageAccount.name,
        policy: {
            rules: [{
                name: "deleteOldVersions",
                type: "Lifecycle",
                definition: {
                    actions: {
                        version: {
                            delete: { daysAfterCreationGreaterThan: 90 }
                        }
                    },
                    filters: { blobTypes: ["blockBlob"] }
                }
            }]
        }
    });
    

    storage-file-encrypted-check

    Severity: high · Enforcement: advisory

    Ensure Azure Storage Files have encryption enabled for data protection.

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Azure Files encryption

    Set encryption on the Storage Account with Files service included. Optionally set keySource to ‘Microsoft.Keyvault’ if customer-managed keys are required.

    subnet-auto-assign-public-ip

    Severity: high · Enforcement: advisory

    Ensure subnet auto-assign public IP is disabled.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Subnet Auto-Assign Public IP

    Your subnet has defaultOutboundAccess enabled (or not explicitly set to false), which allows automatic public IP assignment to resources. Disable this to prevent resources from receiving public IPs by default:

    const subnet = new azure.network.Subnet("mySubnet", {
        virtualNetworkName: vnet.name,
        resourceGroupName: resourceGroup.name,
        addressPrefix: "10.0.1.0/24",
        defaultOutboundAccess: false,  // Disable auto-assign public IP
        networkSecurityGroup: {
            id: nsg.id,  // Associate with NSG for traffic control
        },
    });
    

    If your resources need outbound internet access, use a NAT Gateway instead:

    const natGateway = new azure.network.NatGateway("myNatGateway", {
        resourceGroupName: resourceGroup.name,
        publicIpAddresses: [{ id: publicIp.id }],
    });
    
    const subnet = new azure.network.Subnet("mySubnet", {
        virtualNetworkName: vnet.name,
        resourceGroupName: resourceGroup.name,
        addressPrefix: "10.0.1.0/24",
        defaultOutboundAccess: false,
        natGateway: { id: natGateway.id },  // Use NAT Gateway for outbound
    });
    

    This ensures resources in the subnet don’t get automatic public IPs while still allowing controlled outbound access.

    subscription-part-of-management-groups

    Severity: medium · Enforcement: advisory

    Ensure subscription is part of Management Groups for proper governance hierarchy.

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Associate Subscription with Management Group

    Your subscription needs to be organized under a management group for proper governance:

    import * as azure from "@pulumi/azure-native";
    
    // Create a management group
    const managementGroup = new azure.management.ManagementGroup("myMgmtGroup", {
        displayName: "Production Environment",
        details: {
            parent: { id: "/providers/Microsoft.Management/managementGroups/root" },
        },
    });
    
    // Associate subscription with the management group
    const mgmtGroupSubscription = new azure.management.ManagementGroupSubscription("subAssociation", {
        groupId: managementGroup.name,
    });
    

    Benefits: Centralized policy management, RBAC inheritance, and organized resource hierarchy.

    synapse-backup-enabled

    Severity: medium · Enforcement: advisory

    Ensure Synapse Analytics backup is enabled.

    • CP-9 Information System Backup — The organization conducts backups of user-level information contained in the information system, system-level information, and information system documentation.
    Remediation
    Fix: Configure Synapse Workspace Backups

    Your Synapse workspace doesn’t have proper backup configuration. While Synapse SQL pools have automatic backups, you need to document and configure backup policies:

    For Dedicated SQL Pools (automatic backups included):

    Dedicated SQL pools automatically create restore points. Configure retention:

    import * as azure from "@pulumi/azure-native";
    
    const sqlPool = new azure.synapse.SqlPool("mySqlPool", {
        workspaceName: synapseWorkspace.name,
        resourceGroupName: resourceGroup.name,
        // ... other properties
        tags: {
            BackupEnabled: "enabled",
            BackupRetentionDays: "7",  // Document your retention policy
            AutomatedBackup: "enabled",
        },
    });
    
    For Spark Pools and workspace artifacts:

    Use Git integration to back up notebooks, pipelines, and other artifacts:

    const workspace = new azure.synapse.Workspace("myWorkspace", {
        // ... other properties
        workspaceRepositoryConfiguration: {
            accountName: "myGitHubAccount",
            repositoryName: "synapse-artifacts",
            collaborationBranch: "main",
            rootFolder: "/",
            type: "WorkspaceGitHubConfiguration",
        },
        tags: {
            BackupEnabled: "enabled",
            PipelineBackup: "enabled",
        },
    });
    

    This ensures your Synapse artifacts are version-controlled and recoverable.

    synapse-configuration-logging

    Severity: medium · Enforcement: advisory

    Ensure Synapse Analytics has comprehensive configuration logging enabled for advanced log analysis.

    • AU-11 Audit Record Retention — The organization retains audit records for a defined time period consistent with records retention policy.
    • AU-12 Audit Generation — The information system provides audit record generation capability for the auditable events defined in AU-2 at organization-defined information system components.
    • AU-6 Audit Review, Analysis, and Reporting — The organization reviews and analyzes information system audit records regularly for indications of inappropriate or unusual activity.
    Remediation
    Fix: Enable Synapse Workspace Configuration Logging

    Your Synapse workspace doesn’t have diagnostic settings configured. Enable comprehensive logging to Log Analytics:

    import * as azure from "@pulumi/azure-native";
    
    const diagnostics = new azure.monitor.DiagnosticSetting("synapseDiagnostics", {
        resourceUri: workspace.id,
        workspaceId: logAnalyticsWorkspace.id,
        logs: [
            { category: "SynapseRbacOperations", enabled: true },
            { category: "GatewayApiRequests", enabled: true },
            { category: "BuiltinSqlReqsEnded", enabled: true },
            { category: "IntegrationPipelineRuns", enabled: true },
            { category: "IntegrationActivityRuns", enabled: true },
            { category: "IntegrationTriggerRuns", enabled: true },
        ],
        metrics: [
            { category: "AllMetrics", enabled: true },
        ],
    });
    

    For long-term retention, also send logs to a storage account:

    const diagnostics = new azure.monitor.DiagnosticSetting("synapseDiagnostics", {
        resourceUri: workspace.id,
        workspaceId: logAnalyticsWorkspace.id,
        storageAccountId: storageAccount.id,
        logs: [
            { category: "SynapseRbacOperations", enabled: true, retentionPolicy: { enabled: true, days: 365 } },
            { category: "GatewayApiRequests", enabled: true, retentionPolicy: { enabled: true, days: 365 } },
            { category: "BuiltinSqlReqsEnded", enabled: true, retentionPolicy: { enabled: true, days: 365 } },
        ],
        metrics: [{ category: "AllMetrics", enabled: true }],
    });
    

    This captures RBAC operations, API requests, SQL queries, and pipeline executions for security analysis and compliance.

    synapse-data-exfiltration-protection

    Severity: high · Enforcement: advisory

    Require Synapse Analytics workspaces to enable data exfiltration protection via managed virtual network

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Enable Data Exfiltration Protection
    const workspace = new azurenative.synapse.Workspace("my-synapse-workspace", {
        managedVirtualNetwork: "default",
        managedVirtualNetworkSettings: {
            preventDataExfiltration: true,
            allowedAadTenantIdsForLinking: [
                "your-aad-tenant-id",
            ],
        },
        // ... other config
    });
    

    synapse-public-network-access

    Severity: high · Enforcement: advisory

    Require Synapse Analytics workspaces to disable public network access

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Disable Public Network Access
    const workspace = new azurenative.synapse.Workspace("my-synapse-workspace", {
        publicNetworkAccess: "Disabled",  // Use private endpoints for connectivity
        // ... other config
    });
    

    synapse-workspace-customer-managed-keys

    Severity: high · Enforcement: advisory

    Require Synapse Analytics workspaces to use customer-managed keys for encryption

    • SC-28 Protection of Information at Rest — The information system protects the confidentiality and integrity of information at rest.
    Remediation
    Fix: Configure Customer-Managed Keys
    const synapseWorkspace = new azurenative.synapse.Workspace("my-synapse-workspace", {
        encryption: {
            cmk: {
                key: {
                    name: "my-encryption-key",
                    keyVaultUrl: "https://my-keyvault.vault.azure.net/",
                },
                kekIdentity: {
                    useSystemAssignedIdentity: true,  // Or use userAssignedIdentity
                },
            },
        },
        // ... other config
    });
    

    update-management-compliance

    Severity: medium · Enforcement: advisory

    Ensure VMs are configured for software updates through Azure Update Management to maintain current software versions and security patches.

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Configure Update Management for VM

    Your VM needs proper update management configuration. Configure automatic updates in the OS profile:

    For Windows VMs:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        osProfile: {
            // ... other properties
            windowsConfiguration: {
                enableAutomaticUpdates: true,  // Enable automatic updates
                patchSettings: {
                    patchMode: "AutomaticByPlatform",  // Or "AutomaticByOS"
                    automaticByPlatformSettings: {
                        rebootSetting: "IfRequired",
                    },
                    assessmentMode: "AutomaticByPlatform",
                },
                provisionVMAgent: true,  // Required for Update Management
            },
        },
    });
    
    For Linux VMs:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        osProfile: {
            // ... other properties
            linuxConfiguration: {
                patchSettings: {
                    patchMode: "AutomaticByPlatform",  // Or "ImageDefault"
                    assessmentMode: "AutomaticByPlatform",
                    automaticByPlatformSettings: {
                        rebootSetting: "IfRequired",
                    },
                },
                provisionVMAgent: true,  // Required for Update Management
            },
        },
    });
    

    Note: The VM Agent must be installed and running for Update Management to work properly.

    update-management-maintenance-configuration

    Severity: high · Enforcement: advisory

    Require stacks with virtual machines to define a Maintenance Configuration scoped for automated patching

    • CM-3 Configuration Change Control — The organization determines the types of changes to the information system that are configuration-controlled.
    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Create a Maintenance Configuration for Patching
    const maintenanceConfig = new azurenative.maintenance.MaintenanceConfiguration("patch-config", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        maintenanceScope: "InGuestPatch",
        extensionProperties: {
            InGuestPatchMode: "User",
        },
        startDateTime: "2025-01-15 02:00",
        duration: "03:00",
        timeZone: "UTC",
        recurEvery: "Week Sunday",
    });
    

    update-management-patch-compliant

    Severity: high · Enforcement: advisory

    Ensure Update Management managed instances have patch compliance.

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Update Management Patch Compliance

    Your VM needs proper patch management configuration. Configure automatic patching:

    For Windows VMs:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        osProfile: {
            // ... other properties
            windowsConfiguration: {
                enableAutomaticUpdates: true,
                patchSettings: {
                    patchMode: "AutomaticByPlatform",
                    automaticByPlatformSettings: {
                        rebootSetting: "IfRequired",
                    },
                },
            },
        },
    });
    
    For Linux VMs:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        osProfile: {
            // ... other properties
            linuxConfiguration: {
                patchSettings: {
                    patchMode: "AutomaticByPlatform",
                    assessmentMode: "AutomaticByPlatform",
                },
            },
        },
    });
    
    For VM Scale Sets:
    const vmss = new azure.compute.VirtualMachineScaleSet("my-vmss", {
        // ... other properties
        virtualMachineProfile: {
            osProfile: {
                windowsConfiguration: {
                    enableAutomaticUpdates: true,
                    patchSettings: {
                        patchMode: "AutomaticByPlatform",
                    },
                },
            },
        },
        automaticRepairsPolicy: {
            enabled: true,
            gracePeriod: "PT10M",
        },
    });
    
    Create an Automation Account for centralized management:
    const automationAccount = new azure.automation.AutomationAccount("update-automation", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Basic",
        },
    });
    
    // Link to Log Analytics workspace for monitoring
    const linkedService = new azure.operationalinsights.LinkedService("automation-link", {
        resourceGroupName: resourceGroup.name,
        workspaceName: logAnalyticsWorkspace.name,
        resourceId: automationAccount.id,
    });
    

    vm-approved-images

    Severity: medium · Enforcement: advisory

    Require pre-approved hardened VM images from trusted publishers

    • CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.
    Remediation
    Fix: Use Approved VM Images
    const vm = new azurenative.compute.VirtualMachine("my-vm", {
        hardwareProfile: { vmSize: "Standard_D2s_v3" },
        storageProfile: {
            imageReference: {
                publisher: "Canonical",              // Use approved publisher
                offer: "UbuntuServer",               // Use approved offer
                sku: "20.04-LTS",                    // Use approved SKU
                version: "latest",
            },
            // ... other config
        },
        // ... other config
    });
    

    vm-detailed-monitoring

    Severity: medium · Enforcement: advisory

    Ensure Virtual Machines have detailed monitoring enabled for security and operational visibility.

    • SI-4 Information System Monitoring — The organization monitors the information system to detect attacks and indicators of potential attacks.
    Remediation
    Fix: Enable Detailed Monitoring for VM

    Your VM lacks proper monitoring configuration. Enable detailed monitoring for security and operational visibility.

    Note: Monitoring agent configuration cannot be validated from VM properties alone. Use VM extensions or Azure Policy to enforce monitoring agent deployment.

    Enable Boot Diagnostics
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        diagnosticsProfile: {
            bootDiagnostics: {
                enabled: true,
                storageUri: storageAccount.primaryBlobEndpoint,  // Optional: specify storage account
            },
        },
    });
    
    Install Monitoring Agents via Extensions

    For comprehensive monitoring, install the Azure Monitor Agent or Log Analytics Agent using VM extensions:

    const workspace = new azure.operationalinsights.Workspace("monitoring-workspace", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "PerGB2018",
        },
    });
    
    // For Linux VMs
    const monitoringExtension = new azure.compute.VirtualMachineExtension("monitoring-ext", {
        resourceGroupName: resourceGroup.name,
        vmName: vm.name,
        publisher: "Microsoft.Azure.Monitor",
        type: "AzureMonitorLinuxAgent",
        typeHandlerVersion: "1.0",
        autoUpgradeMinorVersion: true,
        settings: {
            workspaceId: workspace.customerId,
        },
        protectedSettings: {
            workspaceKey: workspace.primarySharedKey,
        },
    });
    

    vm-in-vnet

    Severity: medium · Enforcement: advisory

    Ensure Virtual Machines are deployed within a Virtual Network for secure network isolation.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Deploy VM in Virtual Network

    Your VM must be deployed within a Virtual Network (VNet) for network isolation. Configure network interfaces properly:

    1. Create a VNet and subnet:
    const vnet = new azure.network.VirtualNetwork("my-vnet", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        addressSpace: {
            addressPrefixes: ["10.0.0.0/16"],
        },
    });
    
    const subnet = new azure.network.Subnet("my-subnet", {
        resourceGroupName: resourceGroup.name,
        virtualNetworkName: vnet.name,
        addressPrefix: "10.0.1.0/24",
    });
    
    1. Create a network interface attached to the subnet:
    const nic = new azure.network.NetworkInterface("my-nic", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        ipConfigurations: [{
            name: "ipconfig1",
            subnet: {
                id: subnet.id,
            },
            privateIPAllocationMethod: "Dynamic",
        }],
    });
    
    1. Attach the network interface to your VM:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        networkProfile: {
            networkInterfaces: [{
                id: nic.id,
                primary: true,
            }],
        },
        // ... other properties
    });
    

    Note: Ensure you’re using Azure Resource Manager (ARM) deployment model, not the classic deployment model.

    vm-managed-identity

    Severity: medium · Enforcement: advisory

    Ensure Virtual Machines have managed identity attached.

    • AC-2 Account Management — The organization manages information system accounts, including establishing, activating, modifying, reviewing, disabling, and removing accounts.
    • IA-5 Authenticator Management — The organization manages information system authenticators by verifying, as part of the initial authenticator distribution, the identity of the individual, group, role, or device receiving the authenticator.
    Remediation
    Fix: Enable Managed Identity for Virtual Machine

    Your VM does not have managed identity configured. Enable managed identity to eliminate the need for storing credentials:

    1. Configure system-assigned managed identity (recommended):
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        identity: {
            type: "SystemAssigned",
        },
    });
    
    1. Alternatively, use user-assigned managed identity:
    const userIdentity = new azure.managedidentity.UserAssignedIdentity("my-identity", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
    });
    
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        identity: {
            type: "UserAssigned",
            userAssignedIdentities: {
                [userIdentity.id]: {},
            },
        },
    });
    
    1. For maximum flexibility, use both system-assigned and user-assigned:
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        identity: {
            type: "SystemAssigned,UserAssigned",
            userAssignedIdentities: {
                [userIdentity.id]: {},
            },
        },
    });
    

    After enabling managed identity, you can grant the VM access to Azure resources without storing credentials in your code.

    vm-no-public-ip

    Severity: high · Enforcement: advisory

    Ensure Virtual Machines have no public IP.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Remove Public IP from Virtual Machine

    Your VM has a public IP address which increases attack surface. Remove it and use secure access methods:

    1. Create VM without public IP address:
    const nic = new azure.network.NetworkInterface("my-nic", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        ipConfigurations: [{
            name: "ipconfig1",
            subnet: {
                id: subnet.id,
            },
            privateIPAllocationMethod: "Dynamic",
            // Do NOT add publicIPAddress here
        }],
    });
    
    const vm = new azure.compute.VirtualMachine("my-vm", {
        // ... other properties
        networkProfile: {
            networkInterfaces: [{
                id: nic.id,
            }],
        },
    });
    
    1. Use Azure Bastion for secure RDP/SSH access (recommended):
    const bastionSubnet = new azure.network.Subnet("AzureBastionSubnet", {
        resourceGroupName: resourceGroup.name,
        virtualNetworkName: vnet.name,
        addressPrefix: "10.0.255.0/27",  // Must be /27 or larger
    });
    
    const bastionPublicIp = new azure.network.PublicIPAddress("bastion-ip", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Standard",
        },
        publicIPAllocationMethod: "Static",
    });
    
    const bastion = new azure.network.BastionHost("my-bastion", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        ipConfigurations: [{
            name: "ipconfig",
            subnet: {
                id: bastionSubnet.id,
            },
            publicIPAddress: {
                id: bastionPublicIp.id,
            },
        }],
    });
    
    1. Use NAT Gateway for outbound internet access only:
    const natGatewayPublicIp = new azure.network.PublicIPAddress("nat-ip", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Standard",
        },
        publicIPAllocationMethod: "Static",
    });
    
    const natGateway = new azure.network.NatGateway("my-nat", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Standard",
        },
        publicIpAddresses: [{
            id: natGatewayPublicIp.id,
        }],
    });
    
    const subnet = new azure.network.Subnet("my-subnet", {
        resourceGroupName: resourceGroup.name,
        virtualNetworkName: vnet.name,
        addressPrefix: "10.0.1.0/24",
        natGateway: {
            id: natGateway.id,
        },
    });
    

    vm-requires-managed-disks

    Severity: medium · Enforcement: advisory

    Require VMs to use managed disks only

    • CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.
    Remediation
    Fix: Configure VM to Use Managed Disks
    const vm = new azurenative.compute.VirtualMachine("my-vm", {
        hardwareProfile: { vmSize: "Standard_D2s_v3" },
        storageProfile: {
            osDisk: {
                createOption: "FromImage",
                managedDisk: {  // Use managed disk, not vhd property
                    storageAccountType: "Premium_LRS",
                },
            },
            dataDisks: [{
                lun: 0,
                createOption: "Empty",
                diskSizeGB: 128,
                managedDisk: {  // Use managed disk, not vhd property
                    storageAccountType: "Premium_LRS",
                },
            }],
            // ... other config
        },
        // ... other config
    });
    

    vm-scale-set-automatic-os-upgrades

    Severity: medium · Enforcement: advisory

    Require VM Scale Sets to have automatic OS upgrades enabled

    • SI-2 Flaw Remediation — The organization identifies, reports, and corrects information system flaws.
    Remediation
    Fix: Enable Automatic OS Upgrades for VM Scale Set
    const vmss = new azurenative.compute.VirtualMachineScaleSet("my-vmss", {
        sku: { name: "Standard_D2s_v3", capacity: 3 },
        upgradePolicy: {
            mode: "Rolling",  // Use Rolling or Automatic mode
            automaticOSUpgradePolicy: {
                enableAutomaticOSUpgrade: true,  // Enable automatic OS upgrades
                disableAutomaticRollback: false,  // Allow automatic rollback on failures
            },
        },
        // ... other config
    });
    

    vm-scale-set-multi-az

    Severity: medium · Enforcement: advisory

    Require VM Scale Sets to span multiple availability zones

    • CP-2 Contingency Plan — The organization develops a contingency plan for the information system that identifies essential missions and business functions.
    Remediation
    Fix: Configure VM Scale Set for Multiple Availability Zones
    const vmss = new azurenative.compute.VirtualMachineScaleSet("my-vmss", {
        sku: { name: "Standard_D2s_v3", capacity: 3 },
        zones: ["1", "2", "3"],  // Deploy across multiple availability zones
        zoneBalance: true,       // Ensure even distribution across zones
        // ... other config
    });
    

    vm-scale-set-no-public-ip

    Severity: critical · Enforcement: advisory

    Require VM Scale Sets to have no public IP addresses

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Remove Public IP Configuration from VM Scale Set
    const vmss = new azurenative.compute.VirtualMachineScaleSet("my-vmss", {
        sku: { name: "Standard_D2s_v3" },
        virtualMachineProfile: {
            networkProfile: {
                networkInterfaceConfigurations: [{
                    name: "vmss-nic",
                    primary: true,
                    ipConfigurations: [{
                        name: "ipconfig1",
                        subnet: { id: subnet.id },
                        // Do NOT include publicIPAddressConfiguration
                    }],
                }],
            },
            // ... other config
        },
    });
    

    vm-scale-set-require-managed-disks

    Severity: medium · Enforcement: advisory

    Require VM Scale Sets to use managed disks only

    • CM-2 Baseline Configuration — The organization develops, documents, and maintains a current baseline configuration of the information system.
    Remediation
    Fix: Configure VM Scale Set to Use Managed Disks
    const scaleSet = new azurenative.compute.VirtualMachineScaleSet("my-scale-set", {
        sku: { name: "Standard_D2s_v3" },
        virtualMachineProfile: {
            storageProfile: {
                osDisk: {
                    createOption: "FromImage",
                    managedDisk: {
                        storageAccountType: "Premium_LRS",  // Use managed disk for OS disk
                    },
                    // Do NOT use vhdContainers property
                },
                dataDisks: [{
                    lun: 0,
                    createOption: "Empty",
                    diskSizeGB: 128,
                    managedDisk: {
                        storageAccountType: "Premium_LRS",  // Use managed disk for data disks
                    },
                }],
                // ... other config
            },
            // ... other config
        },
    });
    

    vmss-load-balancer-healthcheck-required

    Severity: medium · Enforcement: advisory

    Ensure VM Scale Sets have Load Balancer health check required for availability monitoring.

    • CA-7 Continuous Monitoring — The organization develops a continuous monitoring strategy and implements a continuous monitoring program.
    Remediation
    Fix: Configure Load Balancer with Health Checks for VM Scale Set

    Your VM Scale Set lacks load balancer association with health checks. Configure it properly:

    1. Create a Load Balancer with health probes:
    const lb = new azure.network.LoadBalancer("my-lb", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Standard",
        },
        frontendIPConfigurations: [{
            name: "frontend",
            subnet: {
                id: subnet.id,
            },
        }],
        probes: [{
            name: "health-probe",
            protocol: "Http",  // or "Https", "Tcp"
            port: 80,
            requestPath: "/health",  // For HTTP/HTTPS
            intervalInSeconds: 15,
            numberOfProbes: 2,
        }],
        backendAddressPools: [{
            name: "backend-pool",
        }],
        loadBalancingRules: [{
            name: "lb-rule",
            protocol: "Tcp",
            frontendPort: 80,
            backendPort: 80,
            frontendIPConfiguration: {
                id: pulumi.interpolate`${lb.id}/frontendIPConfigurations/frontend`,
            },
            backendAddressPool: {
                id: pulumi.interpolate`${lb.id}/backendAddressPools/backend-pool`,
            },
            probe: {
                id: pulumi.interpolate`${lb.id}/probes/health-probe`,
            },
        }],
    });
    
    1. Associate VM Scale Set with the Load Balancer:
    const vmss = new azure.compute.VirtualMachineScaleSet("my-vmss", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Standard_B2s",
            tier: "Standard",
            capacity: 2,
        },
        virtualMachineProfile: {
            networkProfile: {
                networkInterfaceConfigurations: [{
                    name: "nic-config",
                    primary: true,
                    ipConfigurations: [{
                        name: "ip-config",
                        subnet: {
                            id: subnet.id,
                        },
                        loadBalancerBackendAddressPools: [{
                            id: pulumi.interpolate`${lb.id}/backendAddressPools/backend-pool`,
                        }],
                    }],
                }],
            },
            // ... other properties
        },
    });
    
    1. Alternatively, use Application Gateway with health probes:
    const appGw = new azure.network.ApplicationGateway("my-appgw", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: {
            name: "Standard_v2",
            tier: "Standard_v2",
            capacity: 2,
        },
        probes: [{
            name: "health-probe",
            protocol: "Http",
            path: "/health",
            interval: 30,
            timeout: 30,
            unhealthyThreshold: 3,
            host: "localhost",
        }],
        // ... other configuration
    });
    
    1. Add Application Health Extension to VM Scale Set for enhanced monitoring:
    const vmss = new azure.compute.VirtualMachineScaleSet("my-vmss", {
        // ... other properties
        virtualMachineProfile: {
            extensionProfile: {
                extensions: [{
                    name: "HealthExtension",
                    publisher: "Microsoft.ManagedServices",
                    type: "ApplicationHealthLinux",  // or ApplicationHealthWindows
                    typeHandlerVersion: "1.0",
                    autoUpgradeMinorVersion: true,
                    settings: {
                        protocol: "http",
                        port: 80,
                        requestPath: "/health",
                    },
                }],
            },
            // ... other properties
        },
    });
    

    vnet-ddos-protection

    Severity: high · Enforcement: advisory

    Require Virtual Networks to have DDoS Protection Standard enabled

    • SC-5 Denial of Service Protection — The information system protects against or limits the effects of denial of service attacks.
    Remediation
    Fix: Enable DDoS Protection Standard on Virtual Network
    const vnet = new azurenative.network.VirtualNetwork("my-vnet", {
        enableDdosProtection: true,  // Enable DDoS protection
        ddosProtectionPlan: {
            id: ddosProtectionPlan.id,  // Reference DDoS Protection Plan for Standard tier
        },
        // ... other config
    });
    

    vnet-flow-logs-enabled

    Severity: medium · Enforcement: advisory

    Collect audit logs from VNet flow logs for network monitoring.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable VNet Flow Logs for Network Monitoring

    Your Virtual Network does not have flow logs configured for security monitoring and audit collection. Enable flow logs to track network traffic:

    Step 1: Create a Network Watcher (if not exists)
    const networkWatcher = new azure.network.NetworkWatcher("myNetworkWatcher", {
        resourceGroupName: resourceGroup.name,
        location: "eastus",
    });
    
    Step 2: Create a Storage Account for Flow Logs
    const storageAccount = new azure.storage.StorageAccount("flowlogsstorage", {
        resourceGroupName: resourceGroup.name,
        kind: "StorageV2",
        sku: { name: "Standard_LRS" },
    });
    
    const workspace = new azure.operationalinsights.Workspace("myWorkspace", {
        resourceGroupName: resourceGroup.name,
        sku: { name: "PerGB2018" },
        retentionInDays: 30,
    });
    
    Step 4: Enable Flow Logs on Your VNet/NSG
    const flowLog = new azure.network.FlowLog("myFlowLog", {
        networkWatcherName: networkWatcher.name,
        resourceGroupName: resourceGroup.name,
        targetResourceId: nsg.id,  // Or vnet.id for VNet flow logs
        storageId: storageAccount.id,
        enabled: true,
        retentionPolicy: {
            enabled: true,
            days: 30,
        },
        flowAnalyticsConfiguration: {
            networkWatcherFlowAnalyticsConfiguration: {
                enabled: true,
                workspaceResourceId: workspace.id,
                trafficAnalyticsInterval: 10,
            },
        },
    });
    

    This captures all network traffic for security analysis and compliance audit trails.

    vnet-nsg-associated-to-nic

    Severity: medium · Enforcement: advisory

    Ensure VNet network security groups are associated with network interfaces to maintain proper security controls.

    • SC-7 Boundary Protection — The information system monitors and controls communications at the external boundary of the system and at key internal boundaries within the system.
    Remediation
    Fix: Associate Network Security Group to Network Interface

    Your Network Interface doesn’t have a Network Security Group (NSG) associated with it. NSGs provide network-level access control for your resources.

    Associate NSG to Network Interface
    const nsg = new azure.network.NetworkSecurityGroup("myNSG", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        securityRules: [
            {
                name: "AllowHTTPS",
                priority: 100,
                direction: "Inbound",
                access: "Allow",
                protocol: "Tcp",
                sourcePortRange: "*",
                destinationPortRange: "443",
                sourceAddressPrefix: "*",
                destinationAddressPrefix: "*",
            },
        ],
    });
    
    const nic = new azure.network.NetworkInterface("myNIC", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        networkSecurityGroup: {
            id: nsg.id,
        },
        ipConfigurations: [{
            name: "ipconfig1",
            subnet: { id: subnet.id },
            privateIPAllocationMethod: "Dynamic",
        }],
    });
    

    Note: You can associate NSGs at either the NIC level or the subnet level. NIC-level NSGs provide more granular control, while subnet-level NSGs apply to all resources in the subnet.

    vnet-nsg-unused

    Severity: low · Enforcement: advisory

    Ensure VNet network security groups are not unused to maintain asset inventory hygiene.

    • CM-8 Information System Component Inventory — The organization develops and documents an inventory of information system components that accurately reflects the current information system.
    Remediation
    Fix: Remove Unused Network Security Group

    Your Network Security Group is not associated with any subnet or network interface. Unused NSGs create management overhead and potential security risks.

    Option 1: Associate NSG with a Subnet
    const subnet = new azure.network.Subnet("mySubnet", {
        resourceGroupName: resourceGroup.name,
        virtualNetworkName: vnet.name,
        addressPrefix: "10.0.1.0/24",
        networkSecurityGroup: {
            id: nsg.id,
        },
    });
    
    Option 2: Associate NSG with a Network Interface
    const nic = new azure.network.NetworkInterface("myNIC", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        networkSecurityGroup: {
            id: nsg.id,
        },
        ipConfigurations: [{
            name: "ipconfig1",
            subnet: { id: subnet.id },
        }],
    });
    
    Option 3: Delete Unused NSG

    If the NSG is not needed, remove it from your Pulumi program:

    // Remove or comment out the unused NSG resource
    // const nsg = new azure.network.NetworkSecurityGroup("unusedNSG", {
    //     ...
    // });
    

    Note: Before deleting an NSG, verify it’s not referenced by any resources outside your Pulumi program.

    vnet-public-ip-associated

    Severity: low · Enforcement: advisory

    Ensure VNet public IPs are associated with resources to maintain asset inventory hygiene.

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    Remediation
    Fix: Associate Public IP with a Resource

    Your Public IP Address is not associated with any resource. Unassociated public IPs incur costs and create potential security risks.

    Option 1: Associate with Network Interface
    const publicIP = new azure.network.PublicIPAddress("myPublicIP", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        publicIPAllocationMethod: "Static",
        sku: { name: "Standard" },
    });
    
    const nic = new azure.network.NetworkInterface("myNIC", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        ipConfigurations: [{
            name: "ipconfig1",
            subnet: { id: subnet.id },
            publicIPAddress: {
                id: publicIP.id,
            },
            privateIPAllocationMethod: "Dynamic",
        }],
    });
    
    Option 2: Associate with Load Balancer
    const loadBalancer = new azure.network.LoadBalancer("myLB", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        frontendIPConfigurations: [{
            name: "frontend",
            publicIPAddress: {
                id: publicIP.id,
            },
        }],
    });
    
    Option 3: Delete Unused Public IP

    If not needed, remove it from your Pulumi program:

    // Remove or comment out the unused Public IP resource
    // const publicIP = new azure.network.PublicIPAddress("unusedIP", {
    //     ...
    // });
    

    Note: Unused public IPs incur charges. Delete them if they’re not needed to reduce costs and attack surface.

    wafv2-logging-enabled

    Severity: high · Enforcement: advisory

    Collect audit logs from Web Application Firewall v2 for security monitoring.

    • AU-2 Audit Events — The organization determines that the information system is capable of auditing events and coordinates the security audit function with other organizational entities requiring audit-related information.
    Remediation
    Fix: Enable WAF v2 Audit Logging

    Your Application Gateway WAF v2 doesn’t have comprehensive audit logging configured. WAF logs are essential for threat detection and compliance.

    Configure WAF v2 Diagnostic Settings
    const logAnalyticsWorkspace = new azure.operationalinsights.Workspace("logs", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: { name: "PerGB2018" },
    });
    
    const appGateway = new azure.network.ApplicationGateway("myGateway", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
    
        // Use WAF_v2 SKU
        sku: {
            name: "WAF_v2",
            tier: "WAF_v2",
            capacity: 2,
        },
    
        webApplicationFirewallConfiguration: {
            enabled: true,
            firewallMode: "Prevention",
            ruleSetType: "OWASP",
            ruleSetVersion: "3.2",
        },
    });
    
    const diagnosticSetting = new azure.monitor.DiagnosticSetting("waf-diagnostics", {
        resourceUri: appGateway.id,
        workspaceId: logAnalyticsWorkspace.id,
    
        logs: [
            {
                category: "ApplicationGatewayAccessLog",
                enabled: true,
                retentionPolicy: { enabled: true, days: 30 },
            },
            {
                category: "ApplicationGatewayFirewallLog",
                enabled: true,
                retentionPolicy: { enabled: true, days: 30 },
            },
            {
                category: "ApplicationGatewayPerformanceLog",
                enabled: true,
                retentionPolicy: { enabled: true, days: 30 },
            },
        ],
    
        metrics: [{
            category: "AllMetrics",
            enabled: true,
        }],
    });
    
    Add Storage Account for Long-Term Retention
    const storageAccount = new azure.storage.StorageAccount("waflogstorage", {
        resourceGroupName: resourceGroup.name,
        location: resourceGroup.location,
        sku: { name: "Standard_LRS" },
        kind: "StorageV2",
    });
    
    const diagnosticSetting = new azure.monitor.DiagnosticSetting("waf-diagnostics", {
        resourceUri: appGateway.id,
        workspaceId: logAnalyticsWorkspace.id,
        storageAccountId: storageAccount.id,  // For long-term retention
    
        logs: [
            { category: "ApplicationGatewayAccessLog", enabled: true },
            { category: "ApplicationGatewayFirewallLog", enabled: true },
            { category: "ApplicationGatewayPerformanceLog", enabled: true },
        ],
    });
    

    Note: WAF v2 provides enhanced threat detection. Ensure your Application Gateway uses the WAF_v2 SKU tier for full functionality.

    web-app-auth-settings

    Severity: high · Enforcement: advisory

    Require WebApp to have proper authentication settings configured

    • AC-3 Access Enforcement — The information system enforces approved authorizations for logical access to information and system resources.
    • IA-2 Identification and Authentication (Organizational Users) — The information system uniquely identifies and authenticates organizational users (or processes acting on behalf of organizational users).
    Remediation
    Fix: Configure Authentication Settings
    const authSettings = new azurenative.web.WebAppAuthSettings("mywebapp-auth", {
        enabled: true,  // Enable authentication
        defaultProvider: "AzureActiveDirectory",
        unauthenticatedClientAction: "RedirectToLoginPage",
        tokenStoreEnabled: true,  // Enable secure token management
        azureActiveDirectoryProvider: {
            enabled: true,
            registration: {
                clientId: aadClientId,
            },
        },
        // ... other config
    });
    

      The infrastructure as code platform for any cloud.