Desired State Configuration | Project DSC

Posted by Andrew Wilson on Monday, October 23, 2023

Problem Space

I have often found myself with a peeked interest into any method that will simplify both the on-boarding and return to a given project.

Why the interest you may ask…

Well, in most cases when working on a given project (Greenfield or Brownfield), one member of the team will scout ahead to make sure all the engineering tasks are complete. This often allows the development team to work in parallel without stepping on each others toes or be reclined to a halt due to engineering tasks that can only be conducted by a smaller subset of the team. These tasks often include:

  • Setting up a DevOps project.
  • Setting up a repository.
  • Setting up one or more Azure Subscriptions.
  • Setting up the base frameworks, tooling, and repository structure.
  • Setting up any Infrastructure as Code for the project.
  • Setting up CI/CD pipelines.
  • etc.

For most of these tasks, they will be setup once and be applicable for everyone on the team, no further setup required. However, what about individual local project setup (development environments)?

  • Each contributing member needs to have conducted project setup in order to contribute, but how they setup is un-managed.
  • Setup needs to be documented, but is reliant on members reading and following this documentation.
  • Project setup is a duration of time multiplied by the number of members on the team.
  • In the event of an existing project, if not documented correctly, setting up the local project takes investigation and furthered time spent.

In comes my latest find…

WinGet Configuration

With a package manager such as WinGet, we would typically need to install any pre-requisites in an imperative sequencing of steps such as:

  • Git tooling.
  • NodeJS version x.xx
  • etc..

However, with WinGet Configuration we now have the ability to define declarative configuration as code that documents and setups the list of pre-requisites for the environment though a single command winget configure.

This method becomes an answer to many of the problems stipulated above:

  1. Each contributing member needs to have conducted project setup in order to contribute, but how they setup is un-managed.
    • Through tracked configuration as code there is a repeatable, reliable, and a managed method of setup.
  2. Setup needs to be documented, but is reliant on members reading and following this documentation.
    • Configuration as Code can be used as a documenting method for any pre-requisites their versions, dependencies and conditions. Setup is not reliant on interpretation or human error.
  3. Project setup is a duration of time multiplied by the number of members on the team.
    • Automation of manual setup will reduce time spent by each contributing member.
  4. In the event of an existing project, if not documented correctly, setting up the local project takes investigation and furthered time spent.
    • Projects can be easily returned to with the ability to setup your environment exactly how it was when it was last developed.

Getting Started

To get started, have a review of the WinGet Configuration documentation:

Example

I wanted to take this approach to my blog site so that I have a documented and repeatable setup. This resulted in me creating the following Configuration as Code:

# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2

# Hugo Site DSC
# Installs:
#   - Git
#   - Visual Studio Code
#   - NodeJS
#   - Hugo

properties:
  configurationVersion: 0.2.0
  resources:
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install Git
        allowPrerelease: true
      settings:
        id: Git.Git
        source: winget
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install Visual Studio Code
        allowPrerelease: true
      settings:
        id: Microsoft.VisualStudioCode
        source: winget
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install NodeJS
        allowPrerelease: true
      settings:
        id: OpenJS.NodeJS
        source: winget
        version: '19.8.1'
    - resource: Microsoft.WinGet.DSC/WinGetPackage
      directives:
        description: Install Hugo
        allowPrerelease: true
      settings:
        id: Hugo.Hugo.Extended
        source: winget

Have a go and see what you think.