Dynamically populating component groups in Operations Manager 2007 Distributed Applications

This is one I've been asked about several times and am finally getting around to blogging the answer.  The Distributed Application Designer in Operations Manager 2007 makes creating and modifying distributed applications quite easy.  You can create a component group with a few clicks and then drag in managed objects that are related to the application.  What cannot be done with the designer though is create a component group that is automatically populated through a rule like you can do with Operations Manager groups. 

To illustrate this point, note the distributed application below that represents a simple application with a farm of web servers.  I created this using the Line of Business Web Application template.  The component group Monster Island Web Application Web Sites includes all web sites serving the application.  These were manually added to the distributed application by dragging the appropriate instances into the group.  This is the way that distributed applications are typically built.

image

In this example, any web site called Gargantua should be added to the Web Sites component group.  If a new web server is installed, then we would need to open the Distributed Application Designer and drag this new web site instance to the group.  If we had a means to create a discovery for the component group though, then it would automatically be added once the new web site instance were discovered by Operations Manager.

Creating such a discovery is entirely possible and actually not all that difficult.  You won't be able to use the Operations Console though, and you will need to be familiar with either the Authoring Console or working with management packs in XML.  The basic strategy is to modify the GroupPopulator module for the component group to use a membership rule instead of using specific managed objects. 

I'm going to use the Authoring Console to have a look at this discovery.  Since I created it in the Operations Console, the name of it is going to be pretty ugly.  If you have a large management pack, it might take a little searching to find the right item.  The name will start with SC_, and it will have Microsoft.SystemCenter.GroupPopulator as a data source.  Here's a look at the details of mine.

 

image

 

Note the IncludeList section which has two MonitoringObjectID entries.  Those are the GUIDs of the two web sites that I added to the component group.  If I was to drag a third site into the group, we would see that entry.

The goal is to replace that Membership Rule with one that uses include logic instead of specific instances.  That way whenever the discovery executes, it will dynamically find appropriate objects to add to the component group.  It turns out that the same GroupPopulator that this discovery is based on is used for regular groups in Operations manager.  Groups have a nice wizard in the Operations Console for creating a population rule.  An easy strategy is to create a temporary group using the logic we want, and then copying and paste that logic into the component group discovery.

For this example, I'll create a rule that includes all web sites with the name Gargantua.  I created a dummy group called Temp Group in the Operations Console and used the wizard to create the logic shown in the figure below.

 

 image

 

Viewing the discovery for that group in the Authoring Console, we see an Expression instead of an Include List.  That's exactly what we want to go into our component group discovery.

image

 

In order to pull  this off, you're going to need to edit some XML.  First, export the management pack into an XML file where you can open it with an XML editor or the Authoring Console.  The Authoring Console will launch your editor of choice if you click the Edit button, or you could just open the management pack itself if you're more comfortable with that.  If you don't have an XML editor, then Notepad should work without much trouble.  Launching it from the Authoring Console will load just the XML for the discovery in question, so it shouldn't be too daunting.

The XML for the group discovery is as follows:

  <RuleId>$MPElement$</RuleId>
  <GroupInstanceId>$MPElement[Name="UINameSpace236d6bdf988b4598979fb687226e0729.Group"]$</GroupInstanceId>
  <MembershipRules>
    <MembershipRule>
      <MonitoringClass>$MPElement[Name="System!System.WebSite"]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterInstanceGroupLibrary6062460!Microsoft.SystemCenter.InstanceGroupContainsEntities"]$</RelationshipClass>
      <Expression>
<SimpleExpression>
<ValueExpression>
<Property>$MPElement[Name="System!System.Entity"]/DisplayName$</Property>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>Gargantua</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
    </MembershipRule>
  </MembershipRules>

We only care about the section highlighted in blue.  That's the part of the membership rule that we want to move to our component group discovery.  We can simply copy it out and then paste it over the IncludeList section.

If we edit the component group discovery, then we get the following XML:

  <RuleId>$MPElement$</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <MembershipRules>
    <MembershipRule>
      <MonitoringClass>$MPElement[Name="System!System.WebSite"]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterServiceDesignerLibrary6062460!Microsoft.SystemCenter.ServiceDesigner.WebSiteGroupContainsWebSite"]$</RelationshipClass>
      <IncludeList>
<MonitoringObjectId>{fea25c09-8877-dcf3-5f1a-a67a03ffb34d}</MonitoringObjectId>
<MonitoringObjectId>{4dd57b21-d581-ad4e-36b5-eafc3eeb6994}</MonitoringObjectId>
</IncludeList>
    </MembershipRule>
  </MembershipRules>

In this case, the blue section is the one we want to overwrite with the Expression from the group discovery.  If we do that, we get the following XML which we can then save back into the component group discovery rule:

  <RuleId>$MPElement$</RuleId>
  <GroupInstanceId>$Target/Id$</GroupInstanceId>
  <MembershipRules>
    <MembershipRule>
      <MonitoringClass>$MPElement[Name="System!System.WebSite"]$</MonitoringClass>
      <RelationshipClass>$MPElement[Name="MicrosoftSystemCenterServiceDesignerLibrary6062460!Microsoft.SystemCenter.ServiceDesigner.WebSiteGroupContainsWebSite"]$</RelationshipClass>
      <Expression>
        <SimpleExpression>
          <ValueExpression>
            <Property>$MPElement[Name="System!System.Entity"]/DisplayName$</Property>
          </ValueExpression>
          <Operator>Equal</Operator>
          <ValueExpression>
            <Value>Gargantua</Value>
          </ValueExpression>
        </SimpleExpression>
      </Expression>
    </MembershipRule>
  </MembershipRules>

If you save the management pack after this modification and then import it back into the management group, anytime a new web site is discovered with the name Gargantua it will be added to the Web Sites group in the distributed application. 

The big thing to keep in mind if you use this strategy is that you can't use the Distributed Applications Designer for that application anymore.  If you edit and save it, you're going to overwrite that custom discovery that you just created.  Obviously, the best strategy would be to create the entire application using the designer and then performing your custom modification.