Using Azure Automation Pull DSC service I have a configuration that generates multiple Group
resources to ensure accounts are members of the IIS_IUSRS group (app pool identities). These group resources are generated by looping over data inside the $ConfigurationData
supplied at compile time. This is done per web site. As an example:
$Node.WebSites | foreach {
$site = $_
$appPoolId = $site.AppPoolId
Group appPoolIISUsers
{
GroupName = "IIS_IUSRS"
Credential = $DomainCreds
Ensure = "Present"
MembersToInclude = $appPoolId
}
}
When applied, the LCM and WMI services become unstable and produce multiple errors -- specifically DSC Engine Error 28 and Engine Error 2147749939.
I can apply the same technique and the configuration is successful if applied using Start-DSCConfiguration locally in PUSH mode (vs Pull). The only way I am able to get PULL to work with Azure Automation DSC service is to collect all the desired members into a list and use 1 Group
Resource:
$iis_iusrs = ($appPoolIds | select -Unique)
Group "AppPoolIISUsers"
{
GroupName = "IIS_IUSRS"
Credential = $DomainCreds
Ensure = "Present"
MembersToInclude = $iis_iusrs
}
Is this a bug? Reporting in Azure DSC also goes bonkers too:
Any thoughts or help are greatly appreciated.
UPDATED 21 Nov 2016:
Here is the configuration that I generated and applied locally without using unique groupname
values. There is only 1 IIS_IUSRS group locally on the machine and we do not want multiples. So here is the configuration that applied successfully when running locally (the real config pulls creds from Azure Automation, just reusing here for simplicity):
$cd = @{
AllNodes = @(
@{
NodeName = "*"
PSDscAllowPlainTextPassword = $True
PSDscAllowDomainUser = $True
},
@{
NodeName="localhost"
DC = (Get-Credential)
AppPoolId = (Get-Credential)
WebSites = @(
@{
Name = "app1"
WebsiteName = "app1.contoso.lcl"
AppPoolName = "app1.contoso.lcl"
DestinationFolder = "D:\Content\app1"
IsSecure = $false
HostHeaderName = "app1.contoso.lcl"
AppPoolIdentity = "App1AppPoolId"
},
@{
Name = "app2"
WebsiteName = "app2.contoso.lcl"
AppPoolName = "app2.contoso.lcl"
DestinationFolder = "D:\Content\app2"
IsSecure = $false
HostHeaderName = "app2.contoso.lcl"
AppPoolIdentity = "App2AppPoolId"
},
@{
Name = "app3"
WebsiteName = "app3.contoso.lcl"
AppPoolName = "app3.contoso.lcl"
DestinationFolder = "D:\Content\app3"
IsSecure = $false
HostHeaderName = "app3.contoso.lcl"
AppPoolIdentity = "App3AppPoolId"
}
)
}
)
}
Configuration LocalGroupTest
{
Node $AllNodes.NodeName
{
$Node.WebSites | foreach {
$currentSite = $_
Group "AppPoolIISUsers_AppPool$($currentSite.Name)"
{
GroupName = "IIS_IUSRS"
Credential = $Node.DC
Ensure = "Present"
MembersToInclude = @(($Node.AppPoolId).UserName)
}
}
}
}
Localgrouptest -ConfigurationData $cd -Verbose
Start-DscConfiguration -Path .\localgrouptest -Verbose -Wait -Force
Here are the results from DSC engine:
-a---- 11/18/2016 6:26 PM 4496 localhost.mof
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer WEB01 with user sid S-1-5-21-3606597670-2021226393-1313626409-500.
VERBOSE: [WEB01]: LCM: [ Start Set ]
VERBOSE: [WEB01]: LCM: [ Start Resource ] [[Group]AppPoolIISUsers_AppPoolapp1]
VERBOSE: [WEB01]: LCM: [ Start Test ] [[Group]AppPoolIISUsers_AppPoolapp1]
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp1] A group with the name IIS_IUSRS exists.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp1] Resolving contoso\rmdeployer in the contoso domain.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp1] At least one member rmdeployer of the provided MembersToInclude parameter does not have a match in the existing group IIS_IUSRS.
VERBOSE: [WEB01]: LCM: [ End Test ] [[Group]AppPoolIISUsers_AppPoolapp1] in 8.1410 seconds.
VERBOSE: [WEB01]: LCM: [ Start Set ] [[Group]AppPoolIISUsers_AppPoolapp1]
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp1] Performing the operation "Set" on target "Group: IIS_IUSRS".
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp1] Resolving contoso\rmdeployer in the contoso domain.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp1] Group IIS_IUSRS properties updated successfully.
VERBOSE: [WEB01]: LCM: [ End Set ] [[Group]AppPoolIISUsers_AppPoolapp1] in 5.9270 seconds.
VERBOSE: [WEB01]: LCM: [ End Resource ] [[Group]AppPoolIISUsers_AppPoolapp1]
VERBOSE: [WEB01]: LCM: [ Start Resource ] [[Group]AppPoolIISUsers_AppPoolapp2]
VERBOSE: [WEB01]: LCM: [ Start Test ] [[Group]AppPoolIISUsers_AppPoolapp2]
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp2] A group with the name IIS_IUSRS exists.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp2] Resolving CONTOSO in the rmdeployer domain.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp2] Resolving contoso\rmdeployer in the contoso domain.
VERBOSE: [WEB01]: LCM: [ End Test ] [[Group]AppPoolIISUsers_AppPoolapp2] in 6.2480 seconds.
VERBOSE: [WEB01]: LCM: [ Skip Set ] [[Group]AppPoolIISUsers_AppPoolapp2]
VERBOSE: [WEB01]: LCM: [ End Resource ] [[Group]AppPoolIISUsers_AppPoolapp2]
VERBOSE: [WEB01]: LCM: [ Start Resource ] [[Group]AppPoolIISUsers_AppPoolapp3]
VERBOSE: [WEB01]: LCM: [ Start Test ] [[Group]AppPoolIISUsers_AppPoolapp3]
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp3] A group with the name IIS_IUSRS exists.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp3] Resolving CONTOSO in the rmdeployer domain.
VERBOSE: [WEB01]: [[Group]AppPoolIISUsers_AppPoolapp3] Resolving contoso\rmdeployer in the contoso domain.
VERBOSE: [WEB01]: LCM: [ End Test ] [[Group]AppPoolIISUsers_AppPoolapp3] in 6.2440 seconds.
VERBOSE: [WEB01]: LCM: [ Skip Set ] [[Group]AppPoolIISUsers_AppPoolapp3]
VERBOSE: [WEB01]: LCM: [ End Resource ] [[Group]AppPoolIISUsers_AppPoolapp3]
VERBOSE: [WEB01]: LCM: [ End Set ]
VERBOSE: [WEB01]: LCM: [ End Set ] in 26.6100 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 26.923 seconds
Regardless of Azure Automation DSC, this does not seem to be a valid DSC configuration. If you have more than one website object in $Node.WebSites
, you end up with mutiple Group
resources with the same resource name and key (GroupName
), but different values. This is not allowed in DSC.
Running this:
$Node = @{
WebSites = @(@{AppPoolId="somePoolID1"}, @{AppPoolId="somePoolID2"})
}
Configuration abc {
$Node.WebSites | foreach {
$site = $_
$appPoolId = $site.AppPoolId
Group appPoolIISUsers
{
GroupName = "IIS_IUSRS"
Credential = $DomainCreds
Ensure = "Present"
MembersToInclude = $appPoolId
}
}
}
abc
Produces these errors:
PsDesiredStateConfiguration\Group : A duplicate resource identifier '[Group]appPoolIISUsers' was found while processing the
specification for node ''. Change the name of this resource so that it is unique within the node specification.
At line:9 char:8
+ Group appPoolIISUsers
+ ~~~~~
+ CategoryInfo : InvalidOperation: (:) [Write-Error], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : DuplicateResourceIdInNodeStatement,PsDesiredStateConfiguration\Group
Test-ConflictingResources : A conflict was detected between resources '[Group]appPoolIISUsers (::9::8::Group)' and
'[Group]appPoolIISUsers (::9::8::Group)' in node 'localhost'. Resources have identical key properties but there are differences
in the following non-key properties: 'MembersToInclude'. Values 'somePoolID1' don't match values 'somePoolID2'. Please update
these property values so that they are identical in both cases.
At line:246 char:9
+ Test-ConflictingResources $keywordName $canonicalizedValue $k ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Write-Error], InvalidOperationException
+ FullyQualifiedErrorId : ConflictingDuplicateResource,Test-ConflictingResources
Errors occurred while processing configuration 'abc'.
At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:3588 char:5
+ throw $ErrorRecord
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (abc:String) [], InvalidOperationException
+ FullyQualifiedErrorId : FailToProcessConfiguration
Can you try this and see if it works? It makes each Group resource's name and key unique:
$Node.WebSites | foreach {
$site = $_
$appPoolId = $site.AppPoolId
Group ("appPoolIISUsers" + $appPoolId)
{
GroupName = ("IIS_IUSRS" + $appPoolId)
Credential = $DomainCreds
Ensure = "Present"
MembersToInclude = $appPoolId
}
}
Update based on updated question:
The only reason the configuration that you generated and applied locally without using unique groupname values works is because, even though you reuse the same resource key (GroupName=IIS_IUSRS) between resource instances, the desired state you are declaring that each Group should be in is exactly the same -- all 3 resources set the same group to the exact same state. Your configuration is the same as doing this:
Configuration LocalGroupTest
{
Node $AllNodes.NodeName
{
Group "AppPoolIISUsers_AppPoolapp1"
{
GroupName = "IIS_IUSRS"
Credential = $Node.DC
Ensure = "Present"
MembersToInclude = @(($Node.AppPoolId).UserName)
}
Group "AppPoolIISUsers_AppPoolapp2"
{
GroupName = "IIS_IUSRS"
Credential = $Node.DC
Ensure = "Present"
MembersToInclude = @(($Node.AppPoolId).UserName)
}
Group "AppPoolIISUsers_AppPoolapp3"
{
GroupName = "IIS_IUSRS"
Credential = $Node.DC
Ensure = "Present"
MembersToInclude = @(($Node.AppPoolId).UserName)
}
}
}
As you can see, there's no need for the AppPoolIISUsers_AppPoolapp2
or AppPoolIISUsers_AppPoolapp3
resource instances at all, since they set the exact same state as AppPoolIISUsers_AppPoolapp1
on the same group -- IIS_IUSRS
.
Are you sure this sample is declaring the final state that you're trying to declare? I still think the reason you are hitting the issue you're hitting is because you are trying to reuse the same resource instance name and/or resource instance key (GroupName) in your configuration, but with different values for other resource instance fields (for example, MembersToInclude). This is by design not allowed by DSC, because the same resource instance (Group in this case) cannot be in multiple states, it can only be in one state.