Environments

The environment affects the runtime behavior of a template. It provides a way to override the resource implementations and a mechanism to place parameters that the service needs.

To fully understand the runtime behavior you have to consider what plug-ins are installed on the cloud you’re using.

Environment file format

The environment is a yaml text file that contains two main sections:

parameters

A list of key/value pairs.

resource_registry

Definition of custom resources.

It also can contain some other sections:

parameter_defaults

Default parameters passed to all template resources.

encrypted_parameters

List of encrypted parameters.

event_sinks

List of endpoints that would receive stack events.

parameter_merge_strategies

Merge strategies for merging parameters and parameter defaults from the environment file.

Use the -e option of the openstack stack create command to create a stack using the environment defined in such a file.

You can also provide environment parameters as a list of key/value pairs using the –parameter option of the openstack stack create command.

In the following example the environment is read from the my_env.yaml file and an extra parameter is provided using the –parameter option:

$ openstack stack create my_stack -e my_env.yaml --parameter "param1=val1;param2=val2" -t my_tmpl.yaml

Environment Merging

Parameters and their defaults (parameter_defaults) are merged based on merge strategies in an environment file.

There are three merge strategy types:

overwrite

Overwrites a parameter, existing parameter values are replaced.

merge

Merges the existing parameter value and the new value. String values are concatenated, comma delimited lists are extended and json values are updated.

deep_merge

Json values are deep merged. Not useful for other types like comma delimited lists and strings. If specified for them, it falls back to merge.

You can provide a default merge strategy and/or parameter specific merge strategies per environment file. Parameter specific merge strategy is only used for that parameter. An example of parameter_merge_strategies section in an environment file:

parameter_merge_strategies:
  default: merge
  param1: overwrite
  param2: deep_merge

If no merge strategy is provided in an environment file, overwrite becomes the default merge strategy for all parameters and parameter_defaults in that environment file.

Global and effective environments

The environment used for a stack is the combination of the environment you use with the template for the stack, and a global environment that is determined by your cloud operator. An entry in the user environment takes precedence over the global environment. OpenStack includes a default global environment, but your cloud operator can add additional environment entries.

The cloud operator can add to the global environment by putting environment files in a configurable directory wherever the Orchestration engine runs. The configuration variable is named environment_dir and is found in the [DEFAULT] section of /etc/heat/heat.conf. The default for that directory is /etc/heat/environment.d. Its contents are combined in whatever order the shell delivers them when the service starts up, which is the time when these files are read. If the my_env.yaml file from the example above had been put in the environment_dir then the user’s command line could be this:

openstack stack create my_stack --parameter "some_parm=bla" -t my_tmpl.yaml

Global templates

A global template directory allows files to be pre-loaded in the global environment. A global template is determined by your cloud operator. An entry in the user template takes precedence over the global environment. OpenStack includes a default global template, but your cloud operator can add additional template entries.

The cloud operator can add new global templates by putting template files in a configurable directory wherever the Orchestration engine runs. The configuration variable is named template_dir and is found in the [DEFAULT] section of /etc/heat/heat.conf. The default for that directory is /etc/heat/templates. Its contents are combined in whatever order the shell delivers them when the service starts up, which is the time when these files are read. If the my_tmpl.yaml file from the example below has been put in the template_dir, other templates which we used to create stacks could contain following way to include my_tmpl.yaml in it:

resourceA:
  type: {get_file: "my_tmpl.yaml"}

Usage examples

Define values for template arguments

You can define values for the template arguments in the parameters section of an environment file:

parameters:
  KeyName: heat_key
  InstanceType: m1.micro
  ImageId: F18-x86_64-cfntools

Define defaults to parameters

You can define default values for all template arguments in the parameter_defaults section of an environment file. These defaults are passed into all template resources:

parameter_defaults:
  KeyName: heat_key

Mapping resources

You can map one resource to another in the resource_registry section of an environment file. The resource you provide in this manner must have an identifier, and must reference either another resource’s ID or the URL of an existing template file.

The following example maps a new OS::Networking::FloatingIP resource to an existing OS::Neutron::FloatingIP resource:

resource_registry:
  "OS::Networking::FloatingIP": "OS::Neutron::FloatingIP"

You can use wildcards to map multiple resources, for example to map all OS::Neutron resources to OS::Network:

resource_registry:
  "OS::Network*": "OS::Neutron*"

Override a resource with a custom resource

To create or override a resource with a custom resource, create a template file to define this resource, and provide the URL to the template file in the environment file:

resource_registry:
  "AWS::EC2::Instance": file:///path/to/my_instance.yaml

The supported URL schemes are file, http and https.

Note

The template file extension must be .yaml or .template, or it will not be treated as a custom template resource.

You can limit the usage of a custom resource to a specific resource of the template:

resource_registry:
  resources:
    my_db_server:
      "OS::DBInstance": file:///home/mine/all_my_cool_templates/db.yaml

Pause stack creation, update or deletion on a given resource

If you want to debug your stack as it’s being created, updated or deleted, or if you want to run it in phases, you can set pre-create, pre-update, pre-delete, post-create, post-update and post-delete hooks in the resources section of resource_registry.

To set a hook, add either hooks: $hook_name (for example hooks: pre-update) to the resource’s dictionary. You can also use a list (hooks: [pre-create, pre-update]) to stop on several actions.

You can combine hooks with other resources properties such as provider templates or type mapping:

resource_registry:
  resources:
    my_server:
      "OS::DBInstance": file:///home/mine/all_my_cool_templates/db.yaml
      hooks: pre-create
    nested_stack:
      nested_resource:
        hooks: pre-update
      another_resource:
        hooks: [pre-create, pre-update]

When heat encounters a resource that has a hook, it pauses the resource action until the hook clears. Any resources that depend on the paused action wait as well. Non-dependent resources are created in parallel unless they have their own hooks.

It is possible to perform a wild card match using an asterisk (*) in the resource name. For example, the following entry pauses while creating app_server and database_server, but not server or app_network:

resource_registry:
  resources:
    "*_server":
      hooks: pre-create

Clear hooks by signaling the resource with {unset_hook: $hook_name} (for example {unset_hook: pre-update}).

Retrieving events

By default events are stored in the database and can be retrieved via the API. Using the environment, you can register an endpoint which will receive events produced by your stack, so that you don’t have to poll Heat.

You can specify endpoints using the event_sinks property:

event_sinks:
  - type: zaqar-queue
    target: myqueue
    ttl: 1200

Restrict update or replace of a given resource

If you want to restrict update or replace of a resource when your stack is being updated, you can set restricted_actions in the resources section of resource_registry.

To restrict update or replace, add restricted_actions: update or restricted_actions: replace to the resource dictionary. You can also use [update, replace] to restrict both actions.

You can combine restricted actions with other resources properties such as provider templates or type mapping or hooks:

resource_registry:
  resources:
    my_server:
      "OS::DBInstance": file:///home/mine/all_my_cool_templates/db.yaml
      restricted_actions: replace
      hooks: pre-create
    nested_stack:
      nested_resource:
        restricted_actions: update
      another_resource:
        restricted_actions: [update, replace]

It is possible to perform a wild card match using an asterisk (*) in the resource name. For example, the following entry restricts replace for app_server and database_server, but not server or app_network:

resource_registry:
  resources:
    "*_server":
      restricted_actions: replace