Skip to content

Best Practices

Designing Composite Resources

1. Prioritize Modularity and Encapsulation

  • Break down configurations into logical, reusable components. For example, a "WebServer" composite resource might combine WindowsFeature, File, and Script resources to install IIS, configure static files, and deploy a website.
  • Example:
    Resource WebServer {
        param (
            [string]$DestinationPath = 'C:\inetpub\wwwroot\index.html',
            [string]$Content = '<h1>Hello from DSC!</h1>'
        )
        Node localhost {
            WindowsFeature IIS {
                Ensure = 'Present'
                Name = 'Web-Server'
            }
            File StaticContent {
                DestinationPath = $DestinationPath
                Contents = $Content
                Ensure = 'Present'
            }
        }
    }
    

2. Use Parameters for Customization

  • Expose parameters to allow users to customize behavior without modifying the resource. For instance, a DatabaseServer composite might accept InstanceName and DataDirectory parameters and use them in its logic.
  • Example:
    Resource DatabaseServer {
        param (
            [string]$InstanceName = 'MSSQLSERVER',
            [string]$DataDirectory = 'C:\MSSQL\Data'
        )
        Node localhost {
            WindowsFeature SQLServer {
                Ensure = 'Present'
                Name = 'SQL-Server'
            }
            Registry SQLConfig {
                Key = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceName\Setup"
                ValueName = 'DataDirectory'
                ValueData = $DataDirectory
                Ensure = 'Present'
            }
        }
    }
    

3. Validate Input Parameters

  • Implement validation to prevent invalid configurations. Use ValidateScript or ValidateRegex to enforce constraints on parameters.

Testing Composite Resources

1. Implement Unit and Integration Tests

  • Use Pester to test individual components and their interactions. For example, verify that a composite resource correctly installs IIS and creates the static content file.
  • Example Pester test:
    Describe 'WebServer Resource' {
        It 'Installs IIS' {
            Mock Get-WindowsFeature { return @{'Web-Server' = @{Install = $true}} }
            WebServer
            Get-WindowsFeature 'Web-Server' | Should -HaveProperty Install -ValueExactly $true
        }
    }
    

2. Leverage the DSC Resource Schema

  • Validate your composite resource against the DSC Resource Schema to ensure compliance with Microsoft standards.

3. Test for Idempotency

  • Ensure your composite resource can apply the desired state multiple times without errors. For example, the File resource should handle idempotent updates to the same file.

Maintaining Composite Resources

1. Version Control and Documentation

  • Store composite resources in a version-controlled repository (e.g., Git). Include documentation explaining the resource’s purpose, parameters, and usage scenarios.

2. Manage Dependencies Explicitly

  • Clearly document dependencies between resources. For example, a DatabaseServer composite might depend on SQLServer and FirewallRule resources.

3. Use Semantic Versioning

  • Follow semantic versioning (e.g., 1.0.0, 2.1.0) to track changes. Major version updates should include backward-compatible improvements, while minor versions may introduce new features.

Versioning and Backward Compatibility

  • Deprecate gracefully: When removing parameters or changing behavior, provide a migration path and deprecation notice.
  • Avoid breaking changes: Ensure updates maintain compatibility with existing configurations unless absolutely necessary.
  • Use Get-DscResource for validation: Verify that your composite resource is recognized by the DSC runtime.

Key takeaways

  • Design for modularity to simplify maintenance and reuse.
  • Thoroughly test with Pester and the DSC Resource Schema.
  • Version control and documentation are critical for collaboration and troubleshooting.
  • Prioritize backward compatibility to avoid disrupting existing deployments.
  • Validate inputs and ensure idempotency for robust, reliable configurations.