Newer
Older
=====================
Multiple Environments
=====================
.. warning::
Support for multiple Kayobe environments is considered experimental: its
design may change in future versions without a deprecation period.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Sometimes it can be useful to support deployment of multiple environments from
a single Kayobe configuration. Most commonly this is to support a deployment
pipeline, such as the traditional development, test, staging and production
combination. Since the Wallaby release, it is possible to include multiple
environments within a single Kayobe configuration, each providing its own
Ansible inventory and variables. This section describes how to use multiple
environments with Kayobe.
Defining Kayobe Environments
============================
By default, a Kayobe configuration directory contains a single environment,
represented by the Ansible inventory located at
``$KAYOBE_CONFIG_PATH/inventory``, extra variables files
(``$KAYOBE_CONFIG_PATH/*.yml``), custom Ansible playbooks and hooks, and Kolla
configuration.
Supporting multiple environments is done through a
``$KAYOBE_CONFIG_PATH/environments`` directory, under which each directory
represents a different environment. Each environment contains its own Ansible
inventory, extra variable files, and Kolla configuration. The following layout
shows two environments called ``staging`` and ``production`` within a single
Kayobe configuration.
.. code-block:: text
$KAYOBE_CONFIG_PATH/
└── environments/
├── production/
│ ├── inventory/
│ │ ├── groups
│ │ ├── group_vars/
│ │ ├── hosts
│ │ ├── host_vars/
│ │ └── overcloud
│ ├── kolla/
│ │ ├── config/
│ │ ├── globals.yml
│ │ └── passwords.yml
│ ├── network-allocation.yml
│ ├── networks.yml
│ └── overcloud.yml
└── staging/
├── inventory/
│ ├── groups
│ ├── group_vars/
│ ├── hosts
│ ├── host_vars/
│ └── overcloud
├── kolla/
│ ├── config/
│ ├── globals.yml
│ └── passwords.yml
├── network-allocation.yml
├── networks.yml
└── overcloud.yml
Naming
------
The environment name ``kayobe`` is reserved for internal use. The name should
be a valid directory name, otherwise there are no other restrictions.
Ansible Inventories
-------------------
Each environment can include its own inventory, which overrides any variable
declaration done in the shared inventory. Typically, a shared inventory may be
used to define groups and group variables, while hosts and host variables would
be set in environment inventories. The following layout (ignoring non-inventory
files) shows an example of multiple inventories.
.. code-block:: text
$KAYOBE_CONFIG_PATH/
├── environments/
│ ├── production/
│ │ ├── inventory/
│ │ │ ├── hosts
│ │ │ ├── host_vars/
│ │ │ └── overcloud
│ └── staging/
│ ├── inventory/
│ │ ├── hosts
│ │ ├── host_vars/
│ │ └── overcloud
└── inventory/
├── groups
└── group_vars/
Custom Kolla Ansible inventories
--------------------------------
Kayobe has a :ref:`feature <custom_kolla_inventory>` to pass through
additional inventories to Kolla Ansible. When using multiple environments,
these are passed though as additional inventories to Ansible. The ordering is
such that the inventory in the base layer of kayobe config overrides the
internal kayobe inventory, and inventory in the environment overrides inventory
in the base layer:
.. code-block:: bash
ansible-playbook -i <internal kayobe inventory> -i <inventory from base layer> -i <inventory from environment>
See :ref:`custom_kolla_inventory` for more details.
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
Shared Extra Variables Files
----------------------------
All of the extra variables files in the Kayobe configuration directory
(``$KAYOBE_CONFIG_PATH/*.yml``) are shared between all environments. Each
environment can override these extra variables through environment-specific
extra variables files
(``$KAYOBE_CONFIG_PATH/environments/<environment>/*.yml``).
This means that all configuration in shared extra variable files must apply to
all environments. Where configuration differs between environments, move the
configuration to extra variables files under each environment.
For example, to add environment-specific DNS configuration for variables in
``dns.yml``, set these variables in
``$KAYOBE_CONFIG_PATH/environments/<environment>/dns.yml``:
.. code-block:: text
$KAYOBE_CONFIG_PATH/
├── dns.yml
└── environments/
├── production/
│ ├── dns.yml
└── staging/
└── dns.yml
Network Configuration
^^^^^^^^^^^^^^^^^^^^^
Networking is an area in which configuration is typically specific to an
environment. There are two main global configuration files that need to be
considered: ``networks.yml`` and ``network-allocation.yml``.
Move the environment-specific parts of this configuration to
environment-specific extra variables files:
* ``networks.yml`` -> ``$KAYOBE_CONFIG_PATH/environments/<environment>/networks.yml``
* ``network-allocation.yml`` -> ``$KAYOBE_CONFIG_PATH/environments/<environment>/network-allocation.yml``
Other network configuration that may differ between environments includes:
* DNS (``dns.yml``)
* network interface names, which may be set via group variables in environment
inventories
Other Configuration
^^^^^^^^^^^^^^^^^^^
Typically it is necessary to customise ``overcloud_group_hosts_map`` in each
environment. This is done via the ``overcloud.yml`` file documented in
:ref:`control-plane-service-placement`.
When using baremetal compute nodes, allocation of TCP ports for serial console
functionality is typically specific to an environment
(``console-allocation.yml``). This file is automatically managed by Kayobe,
like the ``network-allocation.yml`` file.
Kolla Configuration
-------------------
In the Wallaby release, Kolla configuration was independent in each
environment. The Xena release supported combining environment-specific
and shared configuration file content for the following subset of the files:
* ``kolla/config/bifrost/bifrost.yml``
* ``kolla/config/bifrost/dib.yml``
* ``kolla/config/bifrost/servers.yml``
* ``kolla/globals.yml``
* ``kolla/kolla-build.conf``
* ``kolla/repos.yml`` or ``kolla/repos.yaml``
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
The Antelope release expands upon this list to add support for combining Kolla
Ansible custom service configuration. This behaviour is configured using two
variables:
* ``kolla_openstack_custom_config_include_globs``: Specifies which files are
considered when templating the Kolla configuration. The Kayobe defaults
are set using ``kolla_openstack_custom_config_include_globs_default``.
An optional list of additional globs can be set using:
``kolla_openstack_custom_config_include_globs_extra``. These are
combined with ``kolla_openstack_custom_config_include_globs_default``
to produce ``kolla_openstack_custom_config_include_globs``.
Each list entry is a dictionary with the following keys:
* ``enabled``: Boolean which determines if this rule is used. Set to
``false`` to disable the rule.
* ``glob``: String glob matching a relative path in the ``kolla/config``
directory
An example of such a rule:
.. code-block:: yaml
enabled: '{{ kolla_enable_aodh | bool }}'
glob: aodh/**
* ``kolla_openstack_custom_config_rules``: List of rules that specify the
strategy to use when generating a particular file. The Kayobe defaults
are set using ``kolla_openstack_custom_config_rules_default``.
An optional list of additional rules can be set using:
``kolla_openstack_custom_config_rules_extra``. These are
combined with ``kolla_openstack_custom_config_rules_default``
to produce ``kolla_openstack_custom_config_rules``.
Each list entry is a dictionary with the format:
* ``glob``: A glob matching files for this rule to match on (relative to the
search path)
* ``priority``: The rules are processed in increasing priority order with the
first rule matching taking effect
* ``strategy``: How to process the matched file. One of ``copy``,
``concat``, ``template``, ``merge_configs``, ``merge_yaml``
* ``params``: Optional list of additional params to pass to module enacting
the strategy
An example of such a rule:
.. code-block:: yaml
glob: a/path/test.yml
strategy: merge_yaml
priority: 1000
params:
extend_lists: true
The Kayobe defaults fallback to using the ``template`` strategy, with a
priority of 65535. To override this behaviour configure a rule with a lower
priority e.g:
.. code-block:: yaml
glob: horizon/themes/**
strategy: copy
priority: 1000
The default INI merging strategy can be configured using:
``kolla_openstack_custom_config_ini_merge_strategy_default``. It defaults to ``concat``
for backwards compatibility. An alternative strategy is ``merge_configs`` which will
merge the two INI files so that values set in the environment take precedence over values
set in the shared files. The caveat with the ``merge_configs`` strategy is that files
must template to valid INI. This is mostly an issue when you use raw Jinja
tags, for example:
.. code-block:: ini
[defaults]
{% raw %}
{% if inventory_hostname in 'compute' %}
foo=bar
{% else %}
foo=baz
{% endif %}
{% endraw %}
After the first round of templating by Kayobe the raw tags are stripped. This leaves:
.. code-block:: ini
[defaults]
{% if inventory_hostname in 'compute' %}
foo=bar
{% else %}
foo=baz
{% endif %}
Which isn't valid INI (due to the Jinja if blocks) and cannot be merged. In most cases
the templating can be refactored:
.. code-block:: ini
[defaults]
{% raw %}
foo={{ 'bar' if inventory_hostname in 'compute' else 'baz' }}
{% endraw %}
Alternatively, you can use Kolla host or group variables.
Disabling the default rules
^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are some convenience variables to disable a subset of the
rules in ``kolla_openstack_custom_config_rules_default``:
* ``kolla_openstack_custom_config_rules_default_remove``: Allows you remove
a rule by matching on the glob:
.. code-block:: yaml
kolla_openstack_custom_config_rules_default_remove:
- "**/*.ini"
* ``kolla_openstack_custom_config_merge_configs_enabled``: Enables rules for
matching INI files. Default is ``true``.
* ``kolla_openstack_custom_config_merge_yaml_enabled``: Enables rules for
matching YAML files. Default is ``true``.
These allow you to more easily keep in sync with the upstream defaults. If
you had an override on ``kolla_openstack_custom_config_rules``, that
replicated most of ``kolla_openstack_custom_config_rules_default`` you'd have
to keep this in sync with the upstream kayobe defaults.
Search paths
^^^^^^^^^^^^
When merging config files the following locations are "searched" to find
files with an identical relative path:
- ``<environment-path>/kolla/config``
- ``<shared-files-path>/kolla/config``
- ``<kolla-openstack-role-path>/templates/kolla/config``
Not all strategies use all of the files when generating the kolla config.
For instance, the copy strategy will use the first file found when searching
each of the paths.
There is a feature flag: ``kolla_openstack_custom_config_environment_merging_enabled``,
that may be set to ``false`` to prevent Kayobe searching the shared files path
when merging configs. This is to replicate the legacy behaviour where the
environment Kolla custom service configuration was not merged with the base
layer. We still merge the files with Kayobe's defaults in the
``kolla-openstack`` role's internal templates.
Managing Independent Environment Files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For files that are independent in each environment, i.e. they do not support
combining the environment-specific and shared configuration file content, there
are some techniques that may be used to avoid duplication.
For example, symbolic links can be used to share common variable definitions.
It is advised to avoid sharing credentials between environments by making each
Kolla ``passwords.yml`` file unique.
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
Custom Ansible Playbooks and Hooks
----------------------------------
The following files and directories are currently shared across all
environments:
* Ansible playbooks, roles and requirements file under
``$KAYOBE_CONFIG_PATH/ansible``
* Ansible configuration at ``$KAYOBE_CONFIG_PATH/ansible.cfg`` and
``$KAYOBE_CONFIG_PATH/kolla/ansible.cfg``
* Hooks under ``$KAYOBE_CONFIG_PATH/hooks``
Dynamic Variable Definitions
----------------------------
It may be beneficial to define variables in a file shared by multiple
environments, but still set variables to different values based on the
environment. The Kayobe environment in use can be retrieved within Ansible via
the ``kayobe_environment`` variable. For example, some variables from
``$KAYOBE_CONFIG_PATH/networks.yml`` could be shared in the following way:
.. code-block:: yaml
:caption: ``$KAYOBE_CONFIG_PATH/networks.yml``
external_net_fqdn: "{{ kayobe_environment }}-api.example.com"
This would configure the external FQDN for the staging environment at
``staging-api.example.com``, while the production external FQDN would be at
``production-api.example.com``.
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
Environment Dependencies
------------------------
.. warning::
This is an experimental feature and is still subject to change whilst
the design is finalised.
Since the Antelope 14.0.0 release, multiple environments can be layered on top
of each of each other by declaring dependencies in a ``.kayobe-environment``
file located in the environment subdirectory. For example:
.. code-block:: yaml
:caption: ``$KAYOBE_CONFIG_PATH/environments/environment-C/.kayobe-environment``
dependencies:
- environment-B
.. code-block:: yaml
:caption: ``$KAYOBE_CONFIG_PATH/environments/environment-B/.kayobe-environment``
dependencies:
- environment-A
Kayobe uses a dependency resolver to order these environments into a linear
chain. Any dependency cycles in will result in an error. Using the example
above the chain would be resolved to:
.. code-block:: text
C -> B -> A
Where C is the environment with highest precedence. Kayobe will make sure to
include the inventory and extra-vars in an order matching this chain when
running any playbooks.
Mixin environments
^^^^^^^^^^^^^^^^^^
Environment dependencies can be used to design fragments of re-useable
configuration that can be shared across multiple environments. For example:
.. code-block:: yaml
:caption: ``$KAYOBE_CONFIG_PATH/environments/environment-A/.kayobe-environment``
dependencies:
- environment-mixin-1
- environment-mixin-2
- environment-mixin-3
In this case, each environment dependency could provide the configuration
necessary for one or more features. The mixin environments do not necessarily
need to define any dependencies between them, however Kayobe will perform a
topological sort to determine a suitable precedence. Care should be taken to
make sure that environments without an explicit ordering do not modify the same
variables.
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
Final Considerations
--------------------
While it's clearly desirable to keep staging functionally as close to
production, this is not always possible due to resource constraints and other
factors. Test and development environments can deviate further, perhaps only
providing a subset of the functionality available in production, in a
substantially different environment. In these cases it will clearly be
necessary to use environment-specific configuration in a number of files. We
can't cover all the cases here, but hopefully we've provided a set of
techniques that can be used.
Using Kayobe Environments
=========================
Once environments are defined, Kayobe can be instructed to manage them with the
``$KAYOBE_ENVIRONMENT`` environment variable or the ``--environment``
command-line argument:
.. code-block:: console
(kayobe) $ kayobe control host bootstrap --environment staging
.. code-block:: console
(kayobe) $ export KAYOBE_ENVIRONMENT=staging
(kayobe) $ kayobe control host bootstrap
The ``kayobe-env`` environment file in ``kayobe-config`` can also take an
``--environment`` argument, which exports the ``KAYOBE_ENVIRONMENT``
environment variable.
.. code-block:: console
(kayobe) $ source kayobe-env --environment staging
(kayobe) $ kayobe control host bootstrap
Finally, an environment name can be specified under
``$KAYOBE_CONFIG_ROOT/.environment``, which will be used by the ``kayobe-env``
script if no ``--environment`` argument is used. This is particularly useful
when using a separate branch for each environment.
.. code-block:: console
(kayobe) $ echo "staging" > .environment
(kayobe) $ source kayobe-env
(kayobe) $ kayobe control host bootstrap
.. warning::
The locations of the Kolla Ansible source code and Python virtual
environment remain the same for all environments when using the
``kayobe-env`` file. When using the same control host to manage multiple
environments with different versions of Kolla Ansible, clone the Kayobe
configuration in different locations, so that Kolla Ansible source
repositories and Python virtual environments will not conflict with each
other. The generated Kolla Ansible configuration is also shared: Kayobe will
store the name of the active environment under
``$KOLLA_CONFIG_PATH/.environment`` and produce a warning if a conflict is
detected.
Migrating to Kayobe Environments
================================
Kayobe users already managing multiple environments will already have multiple
Kayobe configurations, whether in separate repositories or in different
branches of the same repository. Kayobe provides the ``kayobe environment
create`` command to help migrating to a common repository and branch with
multiple environments. For example, the following commands will create two new
environments for production and staging based on existing Kayobe
configurations.
.. code-block:: console
(kayobe) $ kayobe environment create --source-config-path ~/kayobe-config-prod/etc/kayobe \
--environment production
(kayobe) $ kayobe environment create --source-config-path ~/kayobe-config-staging/etc/kayobe \
--environment staging
This command recursively copies files and directories (except the
``environments`` directory if one exists) under the existing configuration to a
new environment. Merging shared configuration must be done manually.