Skip to content

ZanattaMichael/AzDO-DSC-LCM

Repository files navigation

AzDO-DSC-LCM

Overview

AzDO-DSC-LCM is the Local Configuration Manager (LCM) component for the AzureDevOpsDsc DSC Module. This module helps manage Azure DevOps resources through Desired State Configuration (DSC). Utilizes Datum to merge configuration stubs into larger pieces of configuration which is parsed into the LCM.

Datum

This LCM utilizes Datum from Gael Colas to streamline configuration. For more information on how to implement and use it, please refer to the official documentation or Gael Colas' resources.

Key Functions

  1. Custom Datum Variable Interpolation: Perform custom datum variable interpolation before LCM initialization using the format [x={ $Node.Project }=].

  2. LCM-Based Calculated Properties: Utilize PowerShell subexpressions for calculated properties, such as $( (1 -eq 2 )? $true: $false ), to dynamically determine values.

  3. Custom Variables: Define and reference custom variables within resource properties.

    Variable Configuration

    variables:
      ProjectName: 'Test_Project'
      GroupName: 'Custom_Group_Name'

    Resource Variable Reference

    - name: CON Board Administrators
      condition: $ProjectWorkBoardsStatus -eq 'enabled'
      type: AzureDevOpsDsc/AzDoProjectGroup
      dependsOn:
        - AzureDevOpsDsc/AzDoProject/Project
      properties:
        ProjectName: $ProjectName
        GroupName: $GroupName
  4. Modular LCM Formatting and Validation Rules: Incorporate modular scripts stored in the \LCM Rules\ directory into the module build process. These scripts are responsible for validating and formatting configuration resources to meet specific requirements. They can be modified and extended as needed. The current set of scripts includes:

    • LCM Rules\PreParse\Test-CircularReferences.ps1: Checks for circular references within resources. If this script detects an error, the LCM will not apply any changes.
    • LCM Rules\PreParse\Test-ResourceForIncorrectProperties: Validates resource properties against documented specifications. Errors prevent LCM from applying changes.
    • LCM Rules\Custom\Sort-DependsOn.ps1: Orders resources in the YAML file based on their dependsOn property. This script is mandatory and cannot be bypassed.
  5. Versioned Configuration: Ensure all versions are managed by the LCM to avoid unforeseen issues as new features are introduced.

    Datum.yml

    LCMConfigSettings:
      ConfigurationVersion: 1.0
      AZDOLCMVersion: 1.0
      DSCResourceVersion: 1.0

Enhanced LCM Resource Features

The Local Configuration Manager (LCM) provides a set of features applicable to all Desired State Configuration (DSC) resources, enhancing their flexibility and control. These features include:

  • condition: This feature allows conditional execution of resources. The condition is evaluated before the resource runs, and if it evaluates to $true, the resource is skipped. This is useful for dynamically controlling resource execution based on specific criteria.

    Example:

    - name: CON Board Administrators
      condition: $ProjectWorkBoardsStatus -eq 'enabled'
      type: AzureDevOpsDsc/AzDoProjectGroup
  • postExecutionScript: This feature triggers a script after the resource has been executed. It can be used to perform additional operations or clean-up tasks following the resource's execution. This is helpful for managing state changes or handling post-execution logic.

    Example:

    - name: Project
      type: AzureDevOpsDsc/AzDoProject
      postExecutionScript: if ($Project_Ensure -eq 'Absent') { Stop-TaskProcessing }
  • dependsOn: This feature establishes a dependency chain, ensuring that resources are executed in a specific order. By defining dependencies, you can create a structured sequence of resource execution, where a resource will only run after its dependencies have successfully completed. This is particularly useful in complex configurations where the order of operations is critical.

    Example:

    - name: Default Git Configuration Permissions
      type: AzureDevOpsDsc/AzDoGitPermission
      dependsOn:
        - AzureDevOpsDsc/AzDoProject/Project
        - AzureDevOpsDsc/AzDoProjectGroup/CON Readers
        - AzureDevOpsDsc/AzDoProjectGroup/CON Board Administrators

These features collectively enhance the robustness and adaptability of DSC resources managed by the LCM, allowing for more precise and context-sensitive configuration management.

Configuration Specific Commands

In the realm of configuration, there are specialized commands designed to modify the Local Configuration Manager (LCM) execution process. These commands provide greater control over how configurations are applied and managed. The key commands include:

  • Stop-TaskProcessing: This command halts the processing of tasks. When executed, any resources scheduled to run after this command will be bypassed, effectively skipping their execution. This can be useful for scenarios where you need to prevent certain operations from taking place without altering the entire configuration. For Example:

    - name: Project
        type: AzureDevOpsDsc/AzDoProject
        postExecutionScript: if ($Project_Ensure -eq 'Absent') { Stop-TaskProcessing }

    In this scenario, when the project is set for deletion, it will remove the project and subsequently halt any further tasks from executing within the pipeline.

Deep Dive: Configuration Merging and Executing Process

  1. Datum merges the example configuration based on the resolution precedence.

  2. Once the YAML file for the project has been generated, Datum will execute any [x={ $Node.ProjectPresence }=] script blocks within the _variables property.

  3. The LCM (Local Configuration Manager) ingests the configuration, loading and interpolating all variables and parameters into memory.

  4. The LCM runs the Pre-Parse and Format rules.

  5. The Resources are ordered according to the dependsOn property.

  6. The LCM iterates through each of the Resources and performs the following steps:

    1. Checks if Stop-TaskProcessing has been executed; if so, the resource will be skipped.
    2. Checks for the condition property and executes the statement. The resource will execute on a $true response.
    3. Iterates through all the properties within the resource and executes any calculated properties. This includes variables such as:
    Ensure: $( if ([string]::IsNullOrEmpty($Project_Ensure)) { 'Present' } else { $Project_Ensure } )
    1. Executes the resource.
    2. Upon completion (even in case of an error), the LCM checks for the postExecutionScript property and invokes the code if present.
    Ensure: $( if ([string]::IsNullOrEmpty($Project_Ensure)) { 'Present' } else { $Project_Ensure } )
    1. The resource is executed.
    2. Once completed (even on error). The LCM will check for the postExecutionScript property. It will invoke the code.

Getting Started

  1. Clone the repository: git clone 'https://github.com/ZanattaMichael/AzDO-DSC-LCM' C:\Your-Path

  2. Using the Example Configuration Directory, create a custom datum directory structure following these guidelines:

    1. Lower-Level Rules should be implemented first, such as organizational policies.

    2. Intermediate-Level Rules apply to groups of projects. For example:

      datum.yml

      ResolutionPrecedence:
          # This is a High-Level Policy
          - Projects\$($Node.ProjectPresence)\$($Node.Project)
          # This is an intermediate level policy. Note that $Node.ProjectArea dictates that there potentially are multiple projects that fall under a "Project Area"
          # These can be specified under a higher level policy.
          - ProjectPolicies\$(Node.ProjectArea)\GitPermissions            
          - ProjectPolicies\$(Node.ProjectArea)\GitRepositories
          - ProjectPolicies\$(Node.ProjectArea)\ProjectGroups
          # This is a Low-Level policy.
          - ProjectPolicies\Project
          - OrganizationPolicies\OrganizationGroups
          - OrganizationPolicies\Organization

      Please Note: Lower-level configurations take precedence over higher-level configurations. In the event of a conflict, datum will default to the lower-level settings.

      ($Node.Project).yaml

      # The Project Area can be specified within the end user yaml file.
      ProjectArea: CustomProjectArea
      
      parameters: {}
      
      variables: {
          ProjectDescription: 'Custom Magenta Project. Contact Name: John Doe.',
          ProjectRepositoryName: 'CON_Configuration',
          Project_Service_GitRepositories: 'enabled',
          Project_Service_BuildPipelines: 'enabled',
          Project_Service_AzureArtifact: 'enabled'
      }
    3. Higher-Level Rules describe lower-level areas and project-specific settings.

      Note: Please keep changes within the project YAML configuration to a minimum. This ensures that the project does not become a 'snowflake' and remains consistent with established standards and practices. By minimizing deviations, we maintain uniformity across projects, facilitating easier maintenance, scalability, and collaboration among team members. This approach also reduces the risk of introducing unique complexities that could complicate future updates or integrations.

    4. Please note that any adjustments should adhere to the established hierarchy and rules.

    5. As a general guideline, AVOID altering lookup_options unless you are fully aware of the implications.

  3. Store the Configuration within the Respective Code Environment:

    • Ensure that all configuration files and settings are securely stored within the appropriate code environment to maintain consistency and security.
    • Use environment-specific directories or repositories to manage configurations, ensuring easy access and version control.
  4. Setup the Local Configuration Manager (LCM) using a Self-Hosted Agent within the Azure DevOps Pipeline:

    • Follow the detailed instructions provided in the Azure DevOps Agents Documentation to configure your self-hosted agent.
    • If Using Managed Identity within Azure Arc:
      • Verify that the Agent Pool service is executed under an administrator account to ensure proper permissions and functionality.
    • Grant Permissions for Identity within Azure DevOps (AZDO):
      • Using Managed Identity (Virtual Machine):
        Refer to the Managed Identities Overview for steps on enabling managed identity on virtual machines.
      • Using Managed Identity for Azure Arc:
        Managed identity is already configured. Add the computer account into the Project Collection Administrators group to grant necessary permissions.
      • If Using Personal Access Token (PAT):
        Add the custom identity to Azure DevOps and generate a PAT to authenticate and authorize actions within the pipeline.
  5. Ensure that the Agent Pools have required dependencies

    Ensure that the Agent Pool is equipped with all necessary PowerShell module dependencies as specified in the module manifest file source\azdo-dsc-lcm.psd1. These dependencies are crucial for the proper functioning of the Local Configuration Manager (LCM) within your Azure DevOps environment.

    To install these required modules, execute the following command for each module listed in the manifest:

    Install-Module -Name ModuleName

    Process:

    1. Review the Module Manifest:
    • Open the source\azdo-dsc-lcm.psd1 file to identify all modules listed under the RequiredModules section.
    • Take note of each module name and version specified.
    1. Install Each Module:
    • For every module identified, run the Install-Module command in a PowerShell session with administrative privileges. Replace ModuleName with the actual name of the module you wish to install.

    • Example:

      Install-Module -Name ModuleName
    1. Verify Installation:
    • After installing each module, confirm its presence by running:

      Get-Module -ListAvailable -Name ModuleName
    • This command will list the installed modules and their versions, ensuring they match those required by the manifest.

    1. Update Modules if Necessary:
    • If any module is outdated, update it using:

      Update-Module -Name ModuleName
    1. Check Compatibility:
    • Ensure that the installed modules are compatible with your system and other installed software to prevent conflicts or errors during execution.

    By following these steps, you will ensure that your Agent Pool is fully prepared with all necessary PowerShell dependencies, facilitating seamless operation of your Azure DevOps pipelines.

    Please Note: Maintaining the correct versioning is crucial to prevent LCM compilation errors. Before proceeding with any updates, always verify that the LCMConfigSettings within Datum.yml are compatible. The Local Configuration Manager will reject any configuration that does not meet the specified versioning criteria.

  6. Setup the Azure DevOps Pipeline:

    • TODO: More documentation is required.
    1. Test to Ensure the LCM is Running Correctly:
    • Set the LCM Mode to Test:
      • Switch the LCM to test mode to validate configuration changes without applying them immediately.
    • Look for Runtime Errors:
      • Monitor logs and outputs for any runtime errors or warnings that could indicate misconfigurations or issues needing resolution.
    • Verify Expected Outcomes:
      • Conduct thorough testing to confirm that the LCM behaves as expected, making adjustments as necessary to address any discrepancies or failures.

About

AzureDevOpsDsc LCM with Datum

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published