Using Variables
As environment files get larger and contain multiple user classes, target addresses, and so on, it makes sense to define variables at the top of the file to make the process scalable. Using variables for a small set of environment file configurations is unnecessary, such as only having a single target as seen in the configuration example capturing idmconfig changes, but once you have ten or more targets, creating variables is the optimal approach.
Defining variables
Variables are defined in order to replace default configuration values with values intended for multiple environments, such as in a base environment file, or to replace values for specific environments. See Inheriting environments to understand how environment specific files can be written to inherit values from base environment files. Variables are also used to replace the same value multiple times.
To define variables for an environment file, start by declaring them in an entry named _vars . This is usually at the top of the file:
{ "_vars": { "ad": { "address": "testad.local" } },
Now that the variable has been defined, it can be accessed in the environment file using: ${_vars.ad.address}
Building on the above example, an AD target address override using the variable would be written as:
{ "_vars": { "ad": { "address": "testad.local" } }, "Scenario": {}, "Functional": {}, "Data": { "hid_target_ad": { "ad.json": { "Fields": { "address": "{server=${_vars.ad.address};nameFormat=NT4;}" } } } } }
Defining multiple variables
A common reason for defining variables in an environment file is unrolling a set of variables to numerous pieces of configuration. For example, multiple target addresses can be defined within variables, and installing the Data.hid_target_ad component can then trigger the creation of multiple AD targets with values pulled from the defined _vars . To do that:
First, define the variables:
{ "_vars": { "ad": [ { "id": "AD", "name": "AD", "address": "{server=testad.local;nameFormat=NT4;}", }, { "id": "AD2", "name": "AD2", "address": "{server=testad2.local;nameFormat=NT4;}", } ] },
Then, define the Data.hid_target_ad component override:
"Scenario": {}, "Functional": {}, "Data": { "hid_target_ad": { "ad.json": { "Fields": { "id": “${_vars.ad.id}", "address": “${_vars.ad.address}" } } } } }
In this case, the _vars.ad variable is unrolled from a two-value list into two separate pieces of configuration. When the Data.hid_target_ad component is installed with this configuration, two targets are created: AD and AD2 with their addresses set to their respective values ( {server=testad.local;nameFormat=NT4;}
and {server=testad2.local;nameFormat=NT4;}
).
In some situations, you may not want the variable to expand into multiple pieces of configuration. In those cases, the _in_place flag is used in environment files to control the expansion.
Using the _in_place flag
The _in_place flag exists to allow environment files to apply variable expansions in different ways, depending on the requirements of the person developing the environment. The most common place this is encountered is when dealing with IDMConfig data components to manipulate dependent objects inside the .json data files.
The previous section describe variable unrolling and how you can use it to create multiple pieces of configuration from a single set of override instructions using a list of variables. That expansion is equivalent to "_in_place": false because it is generating a separate object for each value in a list, whereas _in_place": true generates a single object, using the last value in a list.
The Dependents and Prerequisites blocks will be handled as if the “_in_place” flag is true by default. Thus, requiring you to define it as false if you need it to be treated differently. For example if you have a list variable that is only being used in the Dependent object and not also the Parent, you need to manually set the Dependent object using the substitution to "_in_place": false in order for the list substitution to generate multiple Dependent objects.