### Quick Start: Enable Default Monitoring Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/monitoring-guide.md Example of enabling default monitoring for a Virtual Machine resource with a single method call. ```typescript import { VirtualMachine } from "@microsoft/terraform-cdk-constructs/azure-virtualmachine"; import { ActionGroup } from "@microsoft/terraform-cdk-constructs/azure-actiongroup"; // Create action group for alert notifications const actionGroup = new ActionGroup(this, "alerts", { name: "ops-alerts", groupShortName: "OpsTeam", resourceGroupId: resourceGroup.id, emailReceivers: [{ name: "ops-email", emailAddress: "ops@company.com", useCommonAlertSchema: true, }], }); // Create resource with built-in monitoring const vm = new VirtualMachine(this, "vm", { name: "my-vm", location: "eastus", resourceGroupId: resourceGroup.id, // ... other VM configuration ... // Enable monitoring with one line monitoring: VirtualMachine.defaultMonitoring( actionGroup.id, workspaceId // Log Analytics workspace ID ), }); ``` -------------------------------- ### Migration Analysis Output Examples Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md Examples of migration analysis output indicating the type of upgrade. ```text Automatic upgrade: Yes ← Properties will be transformed automatically Automatic upgrade: Partial ← Some changes automatic, some manual Automatic upgrade: No ← Manual code changes required ``` -------------------------------- ### VersionConfig Migration Guide Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/API.md Example of a migration guide URL or path. ```typescript "/docs/migration-guides/v2024-11-01" ``` -------------------------------- ### Simple Example (Recommended for Most Users) Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md This example demonstrates the basic usage of a ResourceGroup construct without explicitly specifying an API version, relying on the framework's automatic version handling. ```typescript import { ResourceGroup } from '@microsoft/terraform-cdk-constructs'; import { App, TerraformStack } from 'cdktf'; class MyStack extends TerraformStack { constructor(scope: App, name: string) { super(scope, name); // Just create your resource - version is handled automatically! const resourceGroup = new ResourceGroup(this, 'MyResourceGroup', { name: 'my-resource-group', location: 'eastus', tags: { environment: 'production' } }); } } ``` -------------------------------- ### Automatic Migration Analysis Output Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md Example output from the framework's automatic migration analysis, detailing breaking changes and estimated effort. ```text Migration from 2023-05-01 to 2024-01-01 analysis: • Breaking changes: 2 • Estimated effort: Medium (4-8 hours) • Automatic upgrade: Partially possible Breaking changes: 1. Property 'accountType' renamed to 'sku.name' 2. Property 'enableHttpsTrafficOnly' now required (was optional) See migration guide for details: /docs/migration-guides/storage-2024-01-01.md ``` -------------------------------- ### Customization: Monitoring Options Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/monitoring-guide.md Example demonstrating how to customize monitoring configurations, such as thresholds and severities. ```typescript monitoring: VirtualMachine.defaultMonitoring( actionGroup.id, workspaceId, { // Customize thresholds cpuThreshold: 90, // Raise CPU alert threshold to 90% memoryThreshold: 524288000, // Lower memory threshold to 500MB // Adjust severities (0=Critical, 1=Error, 2=Warning, 3=Info, 4=Verbose) cpuAlertSeverity: 1, // Make CPU alerts critical // Enable/disable specific alerts enableDiskQueueAlert: false, // Disable disk queue monitoring enableDeletionAlert: true, // Keep deletion tracking } ) ``` -------------------------------- ### Unsupported API Version Error Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md Example of an error message when an unsupported API version is used. ```text Error: Unsupported API version '2022-01-01' for Microsoft.Storage/storageAccounts Supported versions: 2023-05-01, 2024-01-01, 2024-11-01 ``` -------------------------------- ### Get Supported API Versions Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md Example of how to use the supportedVersions() method to retrieve all supported API versions for a resource. ```typescript const storage = new StorageAccount(this, 'storage', { /* ... */ }); console.log(`Supported versions: ${storage.supportedVersions().join(', ')}`); // Output: Supported versions: 2023-05-01, 2024-01-01, 2024-11-01 ``` -------------------------------- ### Multi-Region Monitoring Setup Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-roleassignment/README.md Example demonstrating how to set up monitoring access across multiple regions using a loop. ```typescript const regions = ['eastus', 'westus', 'northeurope']; regions.forEach(region => { new RoleAssignment(this, `monitoring-${region}`, { name: `monitoring-reader-${region}`, roleDefinitionId: '/providers/Microsoft.Authorization/roleDefinitions/43d0d8ad-25c7-4714-9337-8ba259a9fe05', // Monitoring Reader principalId: monitoringServicePrincipal.objectId, scope: `/subscriptions/${subscriptionId}/resourceGroups/rg-${region}`, principalType: 'ServicePrincipal', description: `Monitoring access for ${region} resources`, tags: { region, purpose: 'monitoring', }, }); }); ``` -------------------------------- ### Deprecated Version Warning Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md Example of a warning message indicating a deprecated API version for a storage account. ```bash ⚠️ API version 2023-05-01 for Microsoft.Storage/storageAccounts is deprecated. Consider upgrading to the latest version: 2024-01-01 Support ends: 2024-12-31 Migration guide: /docs/migration-guides/storage-2024-01-01.md ``` -------------------------------- ### Complete End-to-End Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkmanager/README.md A comprehensive example showing a realistic AVNM setup with all child resources, including resource group, virtual networks, subnets, Virtual Network Manager, network groups, and static members. ```typescript import { App, TerraformStack } from "cdktf"; import { AzapiProvider } from "@microsoft/terraform-cdk-constructs/core-azure"; import { ResourceGroup } from "@microsoft/terraform-cdk-constructs/azure-resourcegroup"; import { VirtualNetwork } from "@microsoft/terraform-cdk-constructs/azure-virtualnetwork"; import { Subnet } from "@microsoft/terraform-cdk-constructs/azure-subnet"; import { VirtualNetworkManager, NetworkGroup, NetworkGroupStaticMember, ConnectivityConfiguration, SecurityAdminConfiguration, SecurityAdminRuleCollection, SecurityAdminRule } from "@microsoft/terraform-cdk-constructs/azure-virtualnetworkmanager"; const app = new App(); const stack = new TerraformStack(app, "avnm-complete-example"); // Configure provider new AzapiProvider(stack, "azapi", {}); // Create resource group const resourceGroup = new ResourceGroup(stack, "rg", { name: "rg-network-management", location: "eastus", tags: { Environment: "Production", ManagedBy: "Terraform" } }); // ============================================================================= // CREATE VIRTUAL NETWORKS // ============================================================================= // Hub VNet const hubVnet = new VirtualNetwork(stack, "hub-vnet", { name: "vnet-hub-eastus", location: resourceGroup.props.location!, resourceGroupId: resourceGroup.id, addressSpace: { addressPrefixes: ["10.0.0.0/16"] } }); new Subnet(stack, "hub-subnet", { name: "subnet-gateway", resourceGroupId: resourceGroup.id, virtualNetworkName: hubVnet.props.name!, virtualNetworkId: hubVnet.id, addressPrefix: "10.0.1.0/24" }); // Production Spoke VNet const prodVnet = new VirtualNetwork(stack, "prod-vnet", { name: "vnet-prod-eastus", location: resourceGroup.props.location!, resourceGroupId: resourceGroup.id, addressSpace: { addressPrefixes: ["10.1.0.0/16"] }, tags: { Environment: "Production" } }); new Subnet(stack, "prod-subnet", { name: "subnet-app", resourceGroupId: resourceGroup.id, virtualNetworkName: prodVnet.props.name!, virtualNetworkId: prodVnet.id, addressPrefix: "10.1.1.0/24" }); // Staging VNet const stagingVnet = new VirtualNetwork(stack, "staging-vnet", { name: "vnet-staging-eastus", location: resourceGroup.props.location!, resourceGroupId: resourceGroup.id, addressSpace: { addressPrefixes: ["10.2.0.0/16"] }, tags: { Environment: "Staging" } }); new Subnet(stack, "staging-subnet", { name: "subnet-app", resourceGroupId: resourceGroup.id, virtualNetworkName: stagingVnet.props.name!, virtualNetworkId: stagingVnet.id, addressPrefix: "10.2.1.0/24" }); // ============================================================================= // CREATE VIRTUAL NETWORK MANAGER // ============================================================================= const networkManager = new VirtualNetworkManager(stack, "vnm", { name: "vnm-enterprise", location: resourceGroup.props.location!, resourceGroupName: resourceGroup.props.name!, networkManagerScopes: { subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"] }, networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"], description: "Enterprise network management for production workloads", tags: { Environment: "Production", Purpose: "Network-Management" } }); // ============================================================================= // CREATE NETWORK GROUPS (Using both patterns) // ============================================================================= // Production group using convenience method const productionGroup = networkManager.addNetworkGroup("prod-group", { name: "ng-production", description: "Production virtual networks", memberType: "VirtualNetwork" }); // Staging group using convenience method const stagingGroup = networkManager.addNetworkGroup("staging-group", { name: "ng-staging", description: "Staging virtual networks", memberType: "VirtualNetwork" }); // Hub group using direct instantiation const hubGroup = new NetworkGroup(stack, "hub-group", { name: "ng-hub", networkManagerId: networkManager.id, description: "Hub virtual network", memberType: "VirtualNetwork" }); // ============================================================================= // ADD VNETS TO GROUPS // ============================================================================= new NetworkGroupStaticMember(stack, "prod-vnet-member", { name: "member-prod-vnet", networkGroupId: productionGroup.id, resourceId: prodVnet.id }); new NetworkGroupStaticMember(stack, "staging-vnet-member", { name: "member-staging-vnet", networkGroupId: stagingGroup.id, resourceId: stagingVnet.id }); new NetworkGroupStaticMember(stack, "hub-vnet-member", { name: "member-hub-vnet", networkGroupId: hubGroup.id, resourceId: hubVnet.id }); ``` -------------------------------- ### Controlling Extension Execution Order Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-vmss/README.md This example shows how to control the execution order of extensions by using the `provisionAfterExtensions` property, ensuring that one extension completes before another starts. ```typescript const vmss = new VirtualMachineScaleSet(this, "vmss-ordered", { name: "my-vmss-ordered", location: "eastus", resourceGroupId: resourceGroup.id, sku: { name: "Standard_D2s_v3", capacity: 3 }, virtualMachineProfile: { extensionProfile: { extensions: [ { name: "health-probe", properties: { publisher: "Microsoft.ManagedServices", type: "ApplicationHealthLinux", typeHandlerVersion: "1.0", enableAutomaticUpgrade: true, }, }, { name: "custom-script", properties: { publisher: "Microsoft.Azure.Extensions", type: "CustomScript", typeHandlerVersion: "2.1", provisionAfterExtensions: ["health-probe"], // Run after health probe }, }, ], }, }, }); ``` -------------------------------- ### Complete End-to-End Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkmanager/README.md This code snippet demonstrates the setup and configuration of Azure Virtual Network Manager using Terraform CDK constructs, including network groups, static members, connectivity, and security rules. ```typescript const app = new TerraformStack(); const mandatoryAllows = new NetworkManager(app, "networkmanager", { displayName: "mandatory-allows", scope: "Subscription", scopeId: "/subscriptions/00000000-0000-0000-0000-000000000000", description: "Allows all traffic", networkManagerScope: { displayName: "networkmanager", scope: "Subscription", scopeId: "/subscriptions/00000000-0000-0000-0000-000000000000", }, }); new NetworkGroup(app, "networkgroup", { networkManager: mandatoryAllows, displayName: "network-group", }); new StaticMember(app, "staticmember", { networkGroup: mandatoryAllows.networkGroups.get(0), displayName: "static-member", memberType: "VirtualNetwork", memberId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resource-group-name/providers/Microsoft.Network/virtualNetworks/vnet-name", }); new ConnectivityConfiguration(app, "connectivityconfiguration", { networkManager: mandatoryAllows, displayName: "connectivity-configuration", deleteExistingPeering: true, appliesToGroups: { groupConnectivity: [mandatoryAllows.networkGroups.get(0)], }, hub: { resourceId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/network-manager-hub-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet", resourceType: "VirtualNetwork", }, }); new SecurityAdminConfiguration(app, "securityadminconfiguration", { networkManager: mandatoryAllows, displayName: "security-admin-configuration", }); new SecurityRule(app, "rule-allow-https", { name: "rule-allow-https", ruleCollectionId: mandatoryAllows.id, description: "Allow HTTPS traffic - NSG can still deny if needed", priority: 200, action: "Allow", direction: "Inbound", protocol: "Tcp", destinationPortRanges: ["443"], sources: [ { addressPrefix: "*", addressPrefixType: "IPPrefix" } ], destinations: [ { addressPrefix: "*", addressPrefixType: "IPPrefix" } ] }); app.synth(); ``` -------------------------------- ### windowSize Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/API.md Example values for windowSize. ```typescript "PT5M", "PT15M", "PT30M", "PT1H" ``` -------------------------------- ### Installation Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-vmss/README.md Install the necessary provider for Azure VMSS. ```bash npm install @cdktf/provider-azapi ``` -------------------------------- ### Sunset Version Error Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md Example of an error message indicating a sunset API version for a storage account, requiring immediate migration. ```bash 🚨 API version 2023-01-01 for Microsoft.Storage/storageAccounts has reached sunset. Immediate migration to 2024-01-01 is required. This version will be removed in the next library update. Migration guide: /docs/migration-guides/storage-2024-01-01.md ``` -------------------------------- ### Upgrading API Versions Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualmachine/README.md Example demonstrating how to analyze migration before upgrading and then creating an upgraded VM. ```typescript // Analyze migration before upgrading const currentVm = new VirtualMachine(this, "vm", { apiVersion: "2024-07-01", // ... properties }); const analysis = currentVm.analyzeMigrationTo("2024-07-01"); if (analysis.compatible) { // Safe to upgrade const upgradedVm = new VirtualMachine(this, "vm-upgraded", { apiVersion: "2024-07-01", // ... same properties }); } ``` -------------------------------- ### Monitoring Disabled Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/monitoring-guide.md Example of explicitly disabling monitoring for a virtual machine. ```typescript // Explicitly disable monitoring monitoring: { enabled: false } ``` -------------------------------- ### Option C: Example Usage Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkmanager/CHILD_RESOURCES_PLAN.md Shows how to use the hybrid approach with both convenience methods and separate classes for creating child resources. ```typescript const vnm = new VirtualNetworkManager(this, "vnm", { ... }); // Style 1: Using convenience methods (more fluent) const ng1 = vnm.addNetworkGroup("ng1", { name: "production-vnets", }); // Style 2: Using separate classes (more explicit) const ng2 = new NetworkGroup(this, "ng2", { networkManagerId: vnm.id, name: "test-vnets", }); // For nested children, MUST use separate classes // (No convenience methods for these) const staticMember = new StaticMember(this, "member", { networkGroupId: ng1.id, resourceId: vnetId, }); ``` -------------------------------- ### Unit Test Example for New API Version Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/azapi-testing-architecture.md Provides an example of a unit test for a new API version, verifying the correct API version is set. ```typescript describe("AZAPI {Resource} v2025-01-01 Unit Tests", () => { it("should have correct API version", () => { expect((resource as any).apiVersion).toBe("2025-01-01"); }); // Add tests for new API version features }); ``` -------------------------------- ### Import Granularity Example (Option A) Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkmanager/CHILD_RESOURCES_PLAN.md Demonstrates the benefit of granular imports in Option A, where only necessary constructs are imported, improving efficiency and reducing bundle size. ```typescript import { NetworkGroup, IpamPool } from "@microsoft/terraform-cdk-constructs/azure-virtualnetworkmanager"; ``` -------------------------------- ### Using Extension Helper Methods Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-vmss/README.md This example demonstrates using convenience methods like `customScriptExtension`, `azureMonitorExtension`, and `applicationHealthExtension` to create common extension configurations and then applying them to the VMSS. ```typescript // Custom Script Extension const scriptExt = VirtualMachineScaleSet.customScriptExtension( "install-app", ["https://example.com/install.sh"], "bash install.sh", { suppressFailures: false } ); // Azure Monitor Agent Extension const monitorExt = VirtualMachineScaleSet.azureMonitorExtension( "azure-monitor", false, // isWindows { provisionAfterExtensions: ["install-app"] } ); // Application Health Extension const healthExt = VirtualMachineScaleSet.applicationHealthExtension( "health-ext", "http", 80, false, // isWindows { requestPath: "/health", intervalInSeconds: 5, numberOfProbes: 3, gracePeriod: 600, } ); // Use extensions in VMSS const vmss = new VirtualMachineScaleSet(this, "vmss-helpers", { name: "my-vmss", location: "eastus", resourceGroupId: resourceGroup.id, sku: { name: "Standard_D2s_v3", capacity: 3 }, virtualMachineProfile: { // ... other profile config extensionProfile: { extensions: [healthExt, scriptExt, monitorExt], }, }, }); ``` -------------------------------- ### Installation Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkgatewayconnection/README.md Install the construct using npm. ```bash npm install @cdktf-constructs/azure-virtualnetworkgatewayconnection ``` -------------------------------- ### TypeScript Configuration for AZAPI Tests Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/azapi-testing-architecture.md Example `tsconfig.dev.json` configuration to include AZAPI test directories. ```json { "include": [ "src/**/*.ts", "src/**/test/**/*.ts", "src/azure-*/azapi/**/*.ts" ] } ``` -------------------------------- ### Quick Start - Default Monitoring Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualmachine/README.md Demonstrates how to enable default monitoring for an Azure Virtual Machine using the `VirtualMachine.defaultMonitoring()` static method. It includes creating an Action Group and a Log Analytics workspace, then configuring the VM with these resources for monitoring. ```typescript import { VirtualMachine } from '@microsoft/terraform-cdk-constructs/azure-virtualmachine'; import { ActionGroup } from '@microsoft/terraform-cdk-constructs/azure-actiongroup'; import { LogAnalyticsWorkspace } from '@microsoft/terraform-cdk-constructs/azure-loganalyticsworkspace'; // Create an action group for alerts const actionGroup = new ActionGroup(this, 'alerts', { name: 'vm-alerts', resourceGroupName: resourceGroup.name, emailReceivers: [{ name: 'admin', emailAddress: 'admin@example.com' }] }); // Create or reference a Log Analytics workspace const workspace = new LogAnalyticsWorkspace(this, 'workspace', { name: 'vm-monitoring-workspace', location: 'eastus', resourceGroupName: resourceGroup.name }); // Create VM with default monitoring const vm = new VirtualMachine(this, 'vm', { name: 'production-vm', location: 'eastus', resourceGroupId: resourceGroup.id, hardwareProfile: { vmSize: 'Standard_D2s_v3', }, // ... other VM configuration ... monitoring: VirtualMachine.defaultMonitoring( actionGroup.id, workspace.id ) }); ``` -------------------------------- ### Complete Email Configuration Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-dnszone/README.md A complete example for setting up email (Microsoft 365) using DNS zone constructs. ```typescript import { DnsZone, DnsMxRecord, DnsTxtRecord, DnsCnameRecord } from "@microsoft/terraform-cdk-constructs/azure-dnszone"; // Create DNS zone const dnsZone = new DnsZone(this, "dns-zone", { name: "contoso.com", location: "global", resourceGroupId: resourceGroup.id, }); // MX record for mail routing new DnsMxRecord(this, "mx-record", { name: "@", dnsZoneId: dnsZone.id, ttl: 3600, records: [ { preference: 0, exchange: "contoso-com.mail.protection.outlook.com" }, ], }); // SPF record new DnsTxtRecord(this, "spf-record", { name: "@", dnsZoneId: dnsZone.id, ttl: 3600, records: [ { value: ["v=spf1 include:spf.protection.outlook.com -all"] }, ], }); // Autodiscover for email client configuration new DnsCnameRecord(this, "autodiscover-cname", { name: "autodiscover", dnsZoneId: dnsZone.id, ttl: 3600, cname: "autodiscover.outlook.com", }); // DKIM selectors (values from Microsoft 365 admin) new DnsCnameRecord(this, "dkim1-cname", { name: "selector1._domainkey", dnsZoneId: dnsZone.id, ttl: 3600, cname: "selector1-contoso-com._domainkey.contoso.onmicrosoft.com", }); new DnsCnameRecord(this, "dkim2-cname", { name: "selector2._domainkey", dnsZoneId: dnsZone.id, ttl: 3600, cname: "selector2-contoso-com._domainkey.contoso.onmicrosoft.com", }); // DMARC policy new DnsTxtRecord(this, "dmarc-record", { name: "_dmarc", dnsZoneId: dnsZone.id, ttl: 3600, records: [ { value: ["v=DMARC1; p=reject; rua=mailto:dmarc-reports@contoso.com; pct=100"] }, ], }); ``` -------------------------------- ### Configure Custom DNS Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetwork/README.md Example of configuring custom DNS servers for a hybrid networking setup. ```typescript // ✅ Hybrid networking setup const vnet = new VirtualNetwork(stack, "vnet", { name: "hybrid-vnet", location: "eastus", resourceGroupId: resourceGroup.id, addressSpace: { addressPrefixes: ["10.0.0.0/16"] }, dhcpOptions: { dnsServers: ["10.0.0.4", "10.0.0.5"], // Custom DNS servers }, }); ``` -------------------------------- ### SOA Record (Start of Authority) Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-dnszone/README.md Example of updating the SOA record for a DNS zone. ```typescript import { DnsSoaRecord } from "@microsoft/terraform-cdk-constructs/azure-dnszone"; const soaRecord = new DnsSoaRecord(this, "soa-record", { name: "@", dnsZoneId: dnsZone.id, ttl: 3600, soaRecord: { email: "admin.contoso.com", // @ symbol replaced with . refreshTime: 3600, // How often secondaries check for updates retryTime: 300, // Retry interval if refresh fails expireTime: 2419200, // When secondaries stop serving zone minimumTTL: 300, // Minimum TTL for negative caching }, }); ``` -------------------------------- ### VirtualMachineWinRMConfiguration Initializer Source: https://github.com/azure/terraform-cdk-constructs/blob/main/API.md Example of initializing VirtualMachineWinRMConfiguration. ```typescript import { VirtualMachineWinRMConfiguration } from '@microsoft/terraform-cdk-constructs' const virtualMachineWinRMConfiguration: VirtualMachineWinRMConfiguration = { ... } ``` -------------------------------- ### Production Environment Monitoring Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/monitoring-guide.md Example of configuring monitoring for a production environment with stricter thresholds and critical alert severities. ```typescript // Stricter thresholds with critical severity monitoring: VirtualMachine.defaultMonitoring( prodActionGroup.id, prodWorkspace.id, { cpuThreshold: 80, memoryThreshold: 1073741824, cpuAlertSeverity: 0, // Critical memoryAlertSeverity: 0, // Critical } ) ``` -------------------------------- ### Basic Usage Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-vmss/README.md Example of creating a Virtual Machine Scale Set with Uniform orchestration. ```typescript import { VirtualMachineScaleSet } from "./azure-vmss"; import { ResourceGroup } from "./azure-resourcegroup"; import type { NetworkInterfaceDnsSettings } from "./azure-networkinterface"; const resourceGroup = new ResourceGroup(this, "rg", { name: "my-resource-group", location: "eastus", }); const vmss = new VirtualMachineScaleSet(this, "vmss", { name: "my-vmss", location: "eastus", resourceGroupId: resourceGroup.id, sku: { name: "Standard_D2s_v3", capacity: 3, }, orchestrationMode: "Uniform", upgradePolicy: { mode: "Automatic", }, virtualMachineProfile: { storageProfile: { imageReference: { publisher: "Canonical", offer: "0001-com-ubuntu-server-jammy", sku: "22_04-lts-gen2", version: "latest", }, osDisk: { createOption: "FromImage", managedDisk: { storageAccountType: "Premium_LRS", }, }, }, osProfile: { computerName: "vmss-vm", adminUsername: "azureuser", linuxConfiguration: { disablePasswordAuthentication: true, ssh: { publicKeys: [ { path: "/home/azureuser/.ssh/authorized_keys", keyData: "ssh-rsa AAAAB3NzaC1yc2E...", }, ], }, }, }, networkProfile: { networkInterfaceConfigurations: [ { name: "nic-config", properties: { primary: true, ipConfigurations: [ { name: "ip-config", properties: { subnet: { id: subnet.id, }, }, }, ], }, }, ], }, }, }); ``` -------------------------------- ### Development Environment Monitoring Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/monitoring-guide.md Example of configuring monitoring for a development environment with relaxed thresholds and disabled deletion alerts. ```typescript // Relaxed thresholds for dev monitoring: VirtualMachine.defaultMonitoring( devActionGroup.id, devWorkspace.id, { cpuThreshold: 95, enableDeletionAlert: false, } ) ``` -------------------------------- ### Quick Example of an Integration Test Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/testing.md A TypeScript example demonstrating how to set up an integration test for an Azure Resource Group, including resource naming, system tags, and applying/destroying with cleanup verification. ```typescript import { Testing } from "cdktf"; import { BaseTestStack, TerraformApplyCheckAndDestroy } from "../../testing"; import { TestRunMetadata } from "../../testing/lib/metadata"; import { ResourceGroup } from "../../azure-resourcegroup"; // Generate unique test run metadata const testMetadata = new TestRunMetadata("my-test-integration", { maxAgeHours: 4, }); class MyTestStack extends BaseTestStack { constructor(scope: Construct, id: string) { super(scope, id, { testRunOptions: { maxAgeHours: testMetadata.maxAgeHours, autoCleanup: testMetadata.autoCleanup, cleanupPolicy: testMetadata.cleanupPolicy, }, }); // Generate unique name const rgName = this.generateResourceName( "Microsoft.Resources/resourceGroups", "my-test", ); // Create resource with system tags new ResourceGroup(this, "rg", { name: rgName, location: "eastus", tags: { ...this.getSystemTags(), // System tags for tracking myCustomTag: "value", // Your custom tags }, }); } } describe("My Test", () => { it("should deploy and cleanup resources", () => { const app = Testing.app(); const stack = new MyTestStack(app, "test"); const synthesized = Testing.fullSynth(stack); // Enable cleanup verification TerraformApplyCheckAndDestroy(synthesized, { verifyCleanup: true }); }, 600000); }); ``` -------------------------------- ### Create New Version Directory Structure Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/azapi-testing-architecture.md Illustrates the directory structure for a new API version implementation. ```bash v2025-01-01/ ├── index.ts ├── props.ts ├── {resource-class}.ts └── test/ ├── {ResourceClass}.spec.ts └── {ResourceClass}.integ.ts ``` -------------------------------- ### Hardware Profile Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/API.md Example of specifying the VM size in the hardware profile. ```typescript { vmSize: "Standard_D2s_v3" } ``` -------------------------------- ### Integration Test Version Gating Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/azapi-testing-architecture.md Example of how to implement version gating in integration tests to ensure only the latest version runs. ```typescript import { getLatest{Resource}Version } from "../../versions"; // Only run integration tests for the latest version const CURRENT_VERSION = "2024-11-01"; // This version's API version const IS_LATEST_VERSION = getLatest{Resource}Version() === CURRENT_VERSION; const describeIfLatest = IS_LATEST_VERSION ? describe : describe.skip; describeIfLatest("AZAPI {Resource} v2024-11-01 Integration Tests", () => { // Integration tests only run if this is the latest version let stack: TerraformStack; let fullSynthResult: any; const streamOutput = process.env.STREAM_OUTPUT !== "false"; beforeEach(() => { // Test setup }); afterEach(() => { try { TerraformDestroy(fullSynthResult, streamOutput); } catch (error) { console.error("Error during Terraform destroy:", error); } }); it("should deploy {Resource} successfully", () => { TerraformApplyAndCheckIdempotency(fullSynthResult, streamOutput); }); }); ``` -------------------------------- ### Complete IPAM Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkmanager/README.md A comprehensive example demonstrating the creation of a Network Manager, root IPAM pool, a regional child pool, and a static CIDR allocation. ```typescript import { App, TerraformStack } from "cdktf"; import { AzapiProvider } from "@microsoft/terraform-cdk-constructs/core-azure"; import { ResourceGroup } from "@microsoft/terraform-cdk-constructs/azure-resourcegroup"; import { VirtualNetworkManager, IpamPool, IpamPoolStaticCidr, } from "@microsoft/terraform-cdk-constructs/azure-virtualnetworkmanager"; const app = new App(); const stack = new TerraformStack(app, "ipam-stack"); // Configure provider new AzapiProvider(stack, "azapi", {}); // Create resource group const resourceGroup = new ResourceGroup(stack, "rg", { name: "rg-ipam-demo", location: "eastus", }); // Create Network Manager const networkManager = new VirtualNetworkManager(stack, "vnm", { name: "ipam-network-manager", location: "eastus", resourceGroupName: resourceGroup.props.name, networkManagerScopes: { subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"], }, networkManagerScopeAccesses: ["Connectivity"], description: "Network manager with IPAM capabilities", }); // Create root IPAM pool const rootPool = new IpamPool(stack, "RootPool", { name: "root-pool", location: "eastus", networkManagerId: networkManager.id, addressPrefixes: ["10.0.0.0/8"], displayName: "Production Root Pool", description: "Root IP address pool for all production workloads", }); // Create regional child pool const eastUSPool = new IpamPool(stack, "EastUSPool", { name: "eastus-pool", location: "eastus", networkManagerId: networkManager.id, addressPrefixes: ["10.1.0.0/16"], parentPoolName: rootPool.props.name, displayName: "East US Region Pool", description: "IP pool for East US region", }); // Allocate static CIDR for specific VNet new IpamPoolStaticCidr(stack, "WebTierAllocation", { name: "web-tier-allocation", ipamPoolId: eastUSPool.id, addressPrefixes: ["10.1.10.0/24"], description: "Reserved for web tier VNet", }); app.synth(); ``` -------------------------------- ### SOA Record (Start of Authority) Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-privatednszone/README.md Example of updating the SOA record for an Azure Private DNS Zone. ```typescript import { PrivateDnsSoaRecord } from "@microsoft/terraform-cdk-constructs/azure-privatednszone"; const soaRecord = new PrivateDnsSoaRecord(this, "soa-record", { name: "@", privateDnsZoneId: privateDnsZone.id, ttl: 3600, soaRecord: { email: "admin.contoso.com", // @ symbol replaced with . refreshTime: 3600, // How often secondaries check for updates retryTime: 300, // Retry interval if refresh fails expireTime: 2419200, // When secondaries stop serving zone minimumTtl: 300, // Minimum TTL for negative caching }, }); ``` -------------------------------- ### Import Granularity Example (Option B) Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualnetworkmanager/CHILD_RESOURCES_PLAN.md Shows the import mechanism in Option B, where the entire VirtualNetworkManager construct must be imported even if only a single feature is utilized. ```typescript import { VirtualNetworkManager } from "@microsoft/terraform-cdk-constructs/azure-virtualnetworkmanager"; ``` -------------------------------- ### How to Pin a Version Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md This example demonstrates how to pin a StorageAccount resource to a specific API version by explicitly setting the 'apiVersion' property. ```typescript const storage = new StorageAccount(this, 'storage', { apiVersion: '2023-05-01', // Pinned to specific version name: 'mystorageaccount', location: 'eastus', sku: { name: 'Standard_LRS' } }); ``` -------------------------------- ### Module Naming Convention Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/design_guide.md Example of how Azure CDK modules are named, starting with the 'azure-' prefix followed by the service name. ```plaintext azure-applicationinsights ``` -------------------------------- ### Combining Default Monitoring with Custom Alerts Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualmachine/README.md Demonstrates how to start with default monitoring settings and add custom alerts, such as a network traffic alert, to the configuration. ```typescript import { VirtualMachine } from '@microsoft/terraform-cdk-constructs/azure-virtualmachine'; import { ActionGroup } from '@microsoft/terraform-cdk-constructs/azure-actiongroup'; const actionGroup = new ActionGroup(this, 'alerts', { name: 'vm-alerts', resourceGroupId: resourceGroup.id, emailReceivers: [{ name: 'admin', emailAddress: 'admin@example.com' }] }); // Start with default monitoring and add one custom alert const monitoring = VirtualMachine.defaultMonitoring( actionGroup.id, workspace.id ); // Add a custom network traffic alert monitoring.metricAlerts?.push({ name: 'high-network-traffic', description: 'Alert when network egress exceeds 10GB in 15 minutes', severity: 2, scopes: [], // Auto-set to this VM evaluationFrequency: 'PT5M', windowSize: 'PT15M', criteria: { type: 'StaticThreshold', metricName: 'Network Out Total', metricNamespace: 'Microsoft.Compute/virtualMachines', operator: 'GreaterThan', threshold: 10737418240, // 10GB in bytes timeAggregation: 'Total' }, actions: [{ actionGroupId: actionGroup.id }] }); const vm = new VirtualMachine(this, 'vm', { name: 'production-vm', location: 'eastus', resourceGroupId: resourceGroup.id, hardwareProfile: { vmSize: 'Standard_D2s_v3' }, // ... other VM configuration ... monitoring: monitoring }); ``` -------------------------------- ### Complete Hybrid DNS Setup Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-dnsresolver/README.md This example demonstrates a complete hybrid DNS setup using Azure DNS Private Resolver constructs, including resource group, virtual network, subnets with delegation, DNS Resolver, Inbound Endpoint, and Outbound Endpoint. ```typescript import { DnsResolver, DnsResolverInboundEndpoint, DnsResolverOutboundEndpoint, } from "@microsoft/terraform-cdk-constructs/azure-dnsresolver"; import { ResourceGroup } from "@microsoft/terraform-cdk-constructs/azure-resourcegroup"; import { VirtualNetwork } from "@microsoft/terraform-cdk-constructs/azure-virtualnetwork"; import { Subnet } from "@microsoft/terraform-cdk-constructs/azure-subnet"; // Create resource group const resourceGroup = new ResourceGroup(this, "rg", { name: "dns-resolver-rg", location: "eastus", }); // Create virtual network const vnet = new VirtualNetwork(this, "vnet", { name: "dns-resolver-vnet", location: "eastus", resourceGroupId: resourceGroup.id, addressSpace: { addressPrefixes: ["10.0.0.0/16"], }, }); // Create dedicated subnets with delegation const inboundSubnet = new Subnet(this, "inbound-subnet", { name: "inbound-subnet", virtualNetworkName: vnet.name, virtualNetworkId: vnet.id, resourceGroupId: resourceGroup.id, addressPrefix: "10.0.1.0/28", delegations: [{ name: "Microsoft.Network.dnsResolvers", serviceName: "Microsoft.Network/dnsResolvers", }], }); const outboundSubnet = new Subnet(this, "outbound-subnet", { name: "outbound-subnet", virtualNetworkName: vnet.name, virtualNetworkId: vnet.id, resourceGroupId: resourceGroup.id, addressPrefix: "10.0.2.0/28", delegations: [{ name: "Microsoft.Network.dnsResolvers", serviceName: "Microsoft.Network/dnsResolvers", }], }); // Create DNS Resolver const dnsResolver = new DnsResolver(this, "resolver", { name: "my-dns-resolver", location: "eastus", resourceGroupId: resourceGroup.id, virtualNetworkId: vnet.id, }); // Create Inbound Endpoint (for on-premises to Azure queries) const inboundEndpoint = new DnsResolverInboundEndpoint(this, "inbound", { name: "my-inbound-endpoint", location: "eastus", dnsResolverId: dnsResolver.id, subnetId: inboundSubnet.id, privateIpAddress: "10.0.1.4", privateIpAllocationMethod: "Static", }); // Create Outbound Endpoint (for Azure to on-premises queries) const outboundEndpoint = new DnsResolverOutboundEndpoint(this, "outbound", { name: "my-outbound-endpoint", location: "eastus", dnsResolverId: dnsResolver.id, subnetId: outboundSubnet.id, }); ``` -------------------------------- ### Configuring Public IP Tags and Routing Preference Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-vmss/README.md This example demonstrates how to configure public IP addresses for the VMSS, including setting idle timeout, IP version, IP tags for routing preference, and associating with a public IP prefix. ```typescript const vmss = new VirtualMachineScaleSet(this, "vmss-public-ip", { name: "my-vmss-public-ip", location: "eastus", resourceGroupId: resourceGroup.id, sku: { name: "Standard_D2s_v3", capacity: 3 }, virtualMachineProfile: { networkProfile: { networkInterfaceConfigurations: [{ name: "nic-config", properties: { primary: true, ipConfigurations: [{ name: "ip-config", properties: { subnet: { id: subnet.id }, publicIPAddressConfiguration: { name: "public-ip", properties: { idleTimeoutInMinutes: 10, publicIPAddressVersion: "IPv4", ipTags: [{ ipTagType: "RoutingPreference", tag: "Internet", }], publicIPPrefix: { id: publicIPPrefix.id, }, }, sku: { name: "Standard", tier: "Regional", }, }, }, }], }, }], }, }, }); ``` -------------------------------- ### versionLifecycle Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/API.md Gets version lifecycle information for a specific version. Provides lifecycle metadata including current phase, transition dates, and projected sunset timeline. ```typescript const lifecycle = manager.versionLifecycle('Microsoft.Resources/resourceGroups', '2024-01-01'); if (lifecycle) { console.log(`Current phase: ${lifecycle.phase}`); console.log(`Sunset date: ${lifecycle.estimatedSunsetDate}`); } ``` -------------------------------- ### versionConfig Example Source: https://github.com/azure/terraform-cdk-constructs/blob/main/API.md Gets the configuration for a specific version of a resource type. Retrieves the complete version configuration including schema, lifecycle information, breaking changes, and migration metadata. ```typescript const config = manager.versionConfig('Microsoft.Resources/resourceGroups', '2024-01-01'); if (config) { console.log(`Support level: ${config.supportLevel}`); console.log(`Release date: ${config.releaseDate}`); } ``` -------------------------------- ### Spot VM with Eviction Policy Source: https://github.com/azure/terraform-cdk-constructs/blob/main/src/azure-virtualmachine/README.md Creates a Spot Virtual Machine with a specified eviction policy and maximum price. ```typescript const spotVm = new VirtualMachine(this, "spot-vm", { name: "my-spot-vm", location: "eastus", resourceGroupId: resourceGroup.id, priority: "Spot", evictionPolicy: "Deallocate", billingProfile: { maxPrice: -1, // Pay up to on-demand price }, hardwareProfile: { vmSize: "Standard_D2s_v3", }, storageProfile: { imageReference: { publisher: "Canonical", offer: "0001-com-ubuntu-server-jammy", sku: "22_04-lts-gen2", version: "latest", }, osDisk: { createOption: "FromImage", managedDisk: { storageAccountType: "Standard_LRS", }, }, }, osProfile: { computerName: "myspotvm", adminUsername: "azureuser", linuxConfiguration: { disablePasswordAuthentication: true, ssh: { publicKeys: [ { path: "/home/azureuser/.ssh/authorized_keys", keyData: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", }, ], }, }, }, networkProfile: { networkInterfaces: [ { id: networkInterface.id, }, ], }, tags: { priority: "spot", }, }); ``` -------------------------------- ### Default Behavior: Always Use Latest Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/versioning-and-migrations-user-guide.md This example shows how the framework automatically uses the latest ACTIVE API version when no specific apiVersion is provided for a StorageAccount resource. ```typescript // No apiVersion specified → uses latest automatically const storage = new StorageAccount(this, 'storage', { name: 'mystorageaccount', location: 'eastus', sku: { name: 'Standard_LRS' } // Framework will use 2024-01-01 (or whatever is latest) }); ``` -------------------------------- ### Essential Inputs Example (Best Practice) Source: https://github.com/azure/terraform-cdk-constructs/blob/main/docs/design_guide.md An example demonstrating the best practice of exposing only essential inputs, allowing defaults to handle the rest. ```typescript // ✅ DO - create only the essential required inputs new AzureAks(app, { clusterVersion: '1.25.5', location: 'eastus', } ```