Skip to content

Proposal: Configuration as resource #1499

@michaeltlombardi

Description

@michaeltlombardi

Summary of the new feature / enhancement

As an infrastructure engineer,
I want to define a reusable configuration document that my coworkers can specify like a resource in their configuration documents,
So that we can provide an abstraction over a subset of configuration for readability, composability, and maintainability.

This feature would enable similar functionality for DSC as Puppet defined types, enabling users to define reusable "resources" in the form of a configuration document. This would let a user combine several related resource instances into a single definition that can be parameterized and used in different contexts.

In configuration management, users often find themselves reusing a few low-level resources repeatedly for different subsets of configuration. For example, ensuring a specific version of a package is installed, setting the service for that package, and providing some optional configuration overrides for it.

Proposed technical implementation details (optional)

We could extend the definition for a configuration document to indicate that the document is meant to be reusable as a resource. When a configuration document is used as a resource, it's subject to the normal semantics for discovery, versioning, and so on.

The following snippet shows an example of a hypothetical configuration document as a resource. The field names are placeholders for clarity.

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
manifest:
  type: TailspinToys/Service
  description: Installs and configures the TSToy service on Windows machines.
  version: 1.2.3
  author: TailspinToys
  tags:
    - tstoy
    - Windows
parameters:
  version:
    description: Specifies the version of TSToy to ensure is installed.
    type: string
    defaultValue: "1.2.3"
  packageSource:
    description: Specifies the source from which to install the TSToy package.
    type: string
    defaultValue: winget
  updateAutomatically:
    description: Indicates whether TSToy should check for updates when it starts.
    type: bool
    defaultValue: true
  updateFrequency:
    description: Specifies how often TSToy should check for updates.
    type: string
    allowedValues:
      - daily
      - weekly
      - monthly
    defaultValue: daily

directive:
  resourceDiscovery: duringDeployment

variables:
  frequency:
    daily: 1
    weekly: 7
    monthly: 30

resources:
  - name: Install TSToy
    type: Microsoft.WinGet/Package
    properties:
      version: "[parameters('version')]"
      id: tstoy
      source: "[parameters('packageSource')]"
  - name: TSToy machine settings
    type: TailspinToys.Service/Settings
    properties:
      scope: machine
      updateAutomatically: "[parameters('updateAutomatically')]"
      updateFrequency: >-
        [tryGet(
          variables('frequency'),
          parameters('updateFrequency')
        )]
    dependsOn:
      - "[resourceId('Microsoft.WinGet/Package','Install TSToy')]"
  - name: Enable TSToy service
    type: Microsoft.Windows/Service
    properties:
      name:      tstoy
      state:     running
      startMode: automatic
    dependsOn:
      - "[resourceId('TailspinToys.Service/Settings','TSToy machine settings')]"

In this example, the configuration-document-as-resource metadata is placed under the manifest field. Minimally, users need to give the document a fully qualified type name and version.

While this example is a little contrived, this resource uses a mix of built-in resources (Microsoft.Windows/Service), other public resources (Microsoft.WinGet/Package), and a package published by the same author (TailspinToys.Service/Settings, which is "actually" installed as part of the package). It shows how you can take a relatively complex set of resources to surface a neater resource surface for end users. The alternative option for people would be to develop a resource that handles all of these components together, but that's more fragile and many users won't want to fully author a resource to compose configuration at this relatively low level.

The following snippet shows an instance of this configuration-document resource in an actual configuration:

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Setup TSToy
  type: TailspinToys/Service
  properties:
    updateAutomatically: true
    updateFrequency:     weekly

Considerations

  1. We can't perfectly replicate a resource instance schema from the parameter definitions - might be useful to support a schema field that applies to the parameters (either in the manifest field or per-parameter) to clarify validation requirements. In the example above, the version property is just a string that defaults to 1.0.0. More correctly it should be a semantic version, but that isn't representable in the current data model.
  2. Unless we add a field to enumerate operations, we have to infer available operations by inspecting the resources defined in the configuration.
  3. There are further potential complications, especially around using adapted resources, but I think they are resolvable.
  4. Enabling resources to be developed this way raises the importance of a dsc config resolve command that "expands" the node graph to show the full set of resources that will be applied.
  5. This proposal in some ways mirrors Proposal: Extended Resources #611, though it's more limited - extendable resources enables you to do relatively complex processing and then hand off all or some of the actual system-modifying logic to another resource. In this model, you're limited to what you can express in a configuration document. I think this proposal still covers numerous use cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Reviewed

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions