DSC icon indicating copy to clipboard operation
DSC copied to clipboard

Should `set` ignore resources that don't support `set`

Open SteveL-MSFT opened this issue 4 months ago • 7 comments

Summary of the new feature / enhancement

It's possible a resource supports export, but not set and with an upcoming change, get will be called when attempting an export if the resource doesn't support it directly. Now imagine you've exported current state (which might even include the OSinfo resource which only supports get).

I can imagine a scenario where a user wants to turn around and deploy this exported config as set, but it will fail once it hits a resource that doesn't support set.

Proposed technical implementation details (optional)

A potential solution is that the user can either opt-in or opt-out of the default behavior of whether set ignores (or warns) on resources that don't implement set rather than outright error and fail.

In this case, a resource that ONLY supports get is effectively read-only. So I would argue that the user should understand this and thus read-only properties are ignored instead of erroring. In which case, the default behavior is to ignore (and if not explicitly opt-ed out emit a warning message) and the user can apply metadata per resource or at document level to explicitly opt-in or opt-out of ignoring:

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
contentVersion: 1.0.0
resources:
- metadata:
    Microsoft.DSC:
      setNotImplemented: Ignore | Warning | Error
  type: Microsoft/OSInfo
  name: Microsoft/OSInfo-0
  properties:
    $id: https://developer.microsoft.com/json-schemas/dsc/os_info/20230303/Microsoft.Dsc.OS_Info.schema.json
    family: macOS
    version: 15.6.0
    bitness: '64'
    architecture: arm64

SteveL-MSFT avatar Aug 07 '25 21:08 SteveL-MSFT

Could you provide a document level opt-in/out example?

ThomasNieto avatar Aug 08 '25 17:08 ThomasNieto

@ThomasNieto if we use the proposed metadata above, it would look like:

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
contentVersion: 1.0.0
metadata:
  Microsoft.DSC:
    setNotImplemented: Ignore | Warning | Error
resources:
  type: Microsoft/OSInfo
  name: Microsoft/OSInfo-0
  properties:
    $id: https://developer.microsoft.com/json-schemas/dsc/os_info/20230303/Microsoft.Dsc.OS_Info.schema.json
    family: macOS
    version: 15.6.0
    bitness: '64'
    architecture: arm64

Basically, the same metadata would be at the top level. And you can override it at each resource level.

SteveL-MSFT avatar Aug 08 '25 19:08 SteveL-MSFT

Another alternative would be to collect unsettable resources from export and insert them automatically into a Microsoft.Dsc/Assertion resource - which also clearly indicates to the reader of the exported document that this specific subset of resources can't be enforced, only audited. The main problem with this that I foresee is dependencies between instances defined in the input configuration document (I don't think exported resources currently have a way to indicate dependencies) and needing to do this processing after the resources have returned their exported instances but before emitting the result.

I'm not against implementing the metadata directive, but I do think that its reasonably easy for a user to call dsc config export and not immediately understand which exported resources are settable without looking up every exported resource. This problem is compounded by the use of exporter resources, where the user could relatively easily author a configuration for export without fully understanding every resource it's going to return.

michaeltlombardi avatar Aug 11 '25 14:08 michaeltlombardi

Thinking about this, it might be cleaner to have export add a condition automatically when it knows that the resource doesn't support set, something like condition: "[not(equals(operation(), 'set'))]" where we would need an operation() function that simply returns the current operation

SteveL-MSFT avatar Aug 18 '25 16:08 SteveL-MSFT

The working group discussed the scenario about running get for a particular resource while in a set operation. This would be used when one resource needs to get the output of another. The proposal would be to use the metadata property for the resource instance to tell the DSC engine to only run the get operation even if the resource can support set.

ThomasNieto avatar Oct 01 '25 19:10 ThomasNieto

The working group discussed the possibility of using Bicep Exisitng. After investigation it was determined that this will not work for DSC. Including Steve's comments below:

_From talking to Bicep team, the fundamental thing is that existing leverages reference() with resourceid() to retrieve the instance so you can use it. The problem for DSC is that ARM uses name as an identity while dsc uses key properties for the identity. As such, the semantics don't line up and I don't think we want to enforce a syntax for name that specifies the key properties.

What this currently means is that existing as it's currently designed won't work for DSC._

theJasonHelmick avatar Oct 29 '25 21:10 theJasonHelmick

The WG discussed this and propose metadata to indicate if a resource will be used always for get or test (the two metadata below are mutually exclusive). When assert is used and passes, then you can use reference() to retrieve it.

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
contentVersion: 1.0.0
resources:
  - type: Microsoft/OSInfo
    metadata:
      Microsoft.DSC:
        retrieve[ActualState]: true # get
        assert[ActualState]: true # test
    name: myOS
    properties:
      family: Windows
  - type: Microsoft.Debug/Echo
    name: example
    condition: "[equals(reference(resourceId('Microsoft/OSInfo','myOS')).family,'Windows']"
    properties:
      output: Hello World

SteveL-MSFT avatar Nov 05 '25 19:11 SteveL-MSFT