Version control your FIM Service configuration

Keeping track of your FIM Service configuration can seem like a daunting task. Even more so when you have multiple DEV, QA, and production instances that need to be kept consistent. We can make version controlling the FIM service a lot easier with some simple modifications to the schema, some clever scripts and a bit of process control.

This post will reference the configuration management capabilities of the Lithnet FIM Service PowerShell module, but the same concepts can apply even when using your own tools.

  1. Firstly, break up your FIM service design into components. A component is a collection of resources such as sets, MPRs and workflows that come together to perform a particular function. For example, the self-service password reset functionality can be grouped together as an SSPR component. You might have a group of workflows, sets and email templates that handle expiry notifications. I generally use the following components as a starting point;
    • User Interface (RCDCs, Nav bar links, etc)
    • Email notifications (welcome emails, expiry notifications, etc)
    • Schema (attributes, bindings, resource types)
    • Security model (permissions)
    • SSPR
  2. Create a custom resource in the FIM service for tracking these components and their versions. Create a changeLogEntry resource with a binding for a new version and details attribute. You can use the Import-RMConfig cmdlet to make these schema modifications for you. Save the following XML into a file, and apply the configuration changes with Import-RMConfig

  3. Each component should have its own design document. The component design document defines the configuration of all the objects that make up that component. The document itself should be version controlled, and is the authoritative source of both the version and configuration of the component.
  4. Translate these documents into a set of scripts that can create and update the components. Each document should  have its own script, and the script should be written to allow them to be run repeatedly, supporting both the creation of the necessary resources, and updating any existing objects to the documented configuration. Once again, you can use the Import-RMConfig cmdlet of the Lithnet FIM Service PowerShell Module to do this for you automatically. Each script should create or modify the changeLogEntry for that component to reflect the version in the component design document. The following XML demonstrates creating an email notification component, and updates the change log automatically as part of that process.

  5. If you have differences in parameters between your development, QA, and production configurations, make use of the variables file that the ConfigSync file provides as part of the <Variables import-file=""> attribute. Extract the parameters into a separate variables file for each of your environments. Each variables file should be saved and managed independently, you never want to have to change the file itself whenever you move between versions. When importing the configuration, copy the appropriate environment-specific variables file into the folder where the config xml is stored, and rename it environment-variables.xml (or the name you have chosen to use in your main xml file). As an example, you might have a QA and a production variables file as shown below. When used with the example file above, the #env# placeholder is substituted with either QA or PROD, depending on the file that is used.

  6. Use a source control system to store your component design documents and scripts. You can get a free Visual Studio online account from Microsoft, or if you have an existing system such as GIT, TFS, or SVN service, you can use that.
  7. When you have a tested, working set of components, that you are ready to deploy, bundle them together and create a release. Create a release document that details each component and its version, as well as the changes made since the last version. Move this release through the development, QA, and prod environments as a bundle. If you are using a source control system, branch your source control tree for each release. That way, you have a permanent, point-in-time copy of what each release looked like.

In summary

  1. Don’t try and version control the whole FIM service configuration. Break it down into smaller components, and release them in defined bundles
  2. Use the FIM Service to keep track of its own component versions by creating a custom change log resource
  3. Your design documents are authoritative. Ensure the appropriate controls are in place to make sure documents are kept up to date, and accurate  reflect your components
  4. Ensure your scripts can be run repeatedly, only making changes where needed. (And remember Import-RMConfig does this out-of-the-box)
  5. Never modify your scripts as part of a deployment. Make use of variable files to apply per-environment settings
  6. Use a source control system to give you a complete version and release history