All Nodes Configuration Subset

So I’ve seen examples like this, which allow you to have a general configuration that applies to all nodes and then individually have different node names:

$AllNodes = (
       @{
            NodeName           = "*"
            ShareName        = "ScriptedShare"
            SourcePath         = "\\dc1\Share"
            DestinationPath    = "C:\scripts2"
            Description = "DSC created SMB Share"
       },
       @{
            NodeName           = "S1"
            Role               = "smb"
        },
       @{
            NodeName = "S2"
            Role = "smb"
        }
    );

Is there a way though to apply a configuration to subsets as well as having one for every node, something like this:

    $AllNodes = (
       @{
            NodeName = "*"
            SourcePath = "\\dc1\Share"
       },
       @{
            NodeName = "Masters"
            ShareName = "MasterShare"
            DestinationPath = "C:\sscripts"
            Description = "Master"
       },
       @{
            NodeName = "Slaves"
            ShareName  = "SlaveShare"
            DestinationPath = "C:\mscripts"
            Description = "Slave"
       },
       @{
            NodeName = "S1"
            Role = "Master"
        },
       @{
            NodeName = "S2"
            Role = "Slave"
        }
    );

Or would it just be better to use the same configuration twice with different configuration data? I wouldn’t want to create two different configurations because in my case they would be almost identical. Thanks.

In this case, what you’d probably want is something like this:

$ConfigurationData = @{
    AllNodes = @(
        @{
            NodeName = "*"
            SourcePath = "\\dc1\Share"
        },
        @{
            NodeName = "S1"
            Role = "Master"
        },
        @{
            NodeName = "S2"
            Role = "Slave"
        }
    )

    Roles = @{
        Master = @{
            ShareName = "MasterShare"
            DestinationPath = "C:\sscripts"
            Description = "Master"
        }
        
        Slave = @{
            ShareName  = "SlaveShare"
            DestinationPath = "C:\mscripts"
            Description = "Slave"
        }
    }
}

configuration SomeConfig
{
    Node $AllNodes.Where({$_.Role -eq 'Master'}).NodeName
    {
        SomeResource theResource
        {
            ShareName = $ConfigurationData.Roles['Master'].ShareName
            DestinationPath = $ConfigurationData.Roles['Master'].DestinationPath
        }
    }
}

Aside from the AllNodes key and anything prefixed with “PS”, the ConfigurationData hashtable is your playground. You can put things into it any place you like, but I wouldn’t recommend trying to do weird things inside the AllNodes array (such as defining “Nodes” for settings that apply to groups of nodes, which is sort of what your original code was doing.)

Depending on how you set up the table, you might not even need to bother with the filtered Node statement. In my brief example, I could have done this:

configuration SomeConfig
{
    Node $AllNodes.NodeName
    {
        SomeResource theResource
        {
            ShareName = $ConfigurationData.Roles[$Node.Role].ShareName
            DestinationPath = $ConfigurationData.Roles[$Node.Role].DestinationPath
        }
    }
}

Dave is dead on IMO, the nice part about the model he listed out also is you can comma delimit the roles so you end up having “complexity hierarchies” within the configuration, so you can have this like:

@{
            NodeName = "S1"
            Role = "FS", "IIS"
    },

I agree, this is a very elegant solution, thank you. This was very helpful.