diff --git a/docs/include_directive.rst b/docs/include_directive.rst new file mode 100644 index 0000000..79465b9 --- /dev/null +++ b/docs/include_directive.rst @@ -0,0 +1,290 @@ +YAML !include Directive +======================= + +The ``!include`` directive is a powerful feature in octoDNS that allows you to +reuse YAML content across multiple configuration files and zone files. This +helps reduce duplication and makes your DNS configuration more maintainable. + +Overview +-------- + +The ``!include`` directive can be used anywhere in your YAML files to include +content from other files. Files are resolved relative to the directory +containing the file with the ``!include`` directive. + +Basic Usage +----------- + +Single File Include +................... + +The simplest form includes the entire contents of a single file:: + + --- + # main.yaml + common-config: !include common.yaml + +If ``common.yaml`` contains:: + + --- + key: value + setting: 42 + +Then ``common-config`` will be set to ``{'key': 'value', 'setting': 42}``. + +The included file can contain any valid YAML type: dictionaries, lists, strings, +numbers, or even ``null`` values. + +Array Syntax +............ + +The ``!include`` directive also supports an array syntax to merge multiple files +together. This is useful for composing configurations from multiple sources. + +Merging Dictionaries +~~~~~~~~~~~~~~~~~~~~~ + +When including multiple files that contain dictionaries, the dictionaries are +merged together. Later files override keys from earlier files:: + + --- + # main.yaml + merged-config: !include + - base-config.yaml + - overrides.yaml + +If ``base-config.yaml`` contains:: + + --- + timeout: 30 + retries: 3 + debug: false + +And ``overrides.yaml`` contains:: + + --- + timeout: 60 + debug: true + added: hi + +Then ``merged-config`` will be:: + + { + 'timeout': 60, # overridden + 'retries': 3, # from base + 'debug': true, # overridden + 'added': 'hi' # added by overrides + } + +Merging Arrays +~~~~~~~~~~~~~~ + +When including multiple files that contain arrays, the arrays are concatenated +together:: + + --- + # main.yaml + all-values: !include + - values-1.yaml + - values-2.yaml + +If ``values-1.yaml`` contains:: + + --- + - item1 + - item2 + +And ``values-2.yaml`` contains:: + + --- + - item3 + - item4 + +Then ``all-values`` will be ``['item1', 'item2', 'item3', 'item4']``. + +Empty Arrays +~~~~~~~~~~~~ + +An empty array can be used with ``!include``, which results in ``null``:: + + --- + empty-value: !include [] + +This sets ``empty-value`` to ``null``. + +Use Cases +--------- + +Configuration Files +................... + +The ``!include`` directive is useful in octoDNS configuration files for sharing +common provider settings, processor configurations, or zone settings. + +Shared Provider Configuration:: + + --- + # production.yaml + providers: + base-config: !include providers/common.yaml + + route53: + class: octodns_route53.Route53Provider + access_key_id: env/AWS_ACCESS_KEY_ID + secret_access_key: env/AWS_SECRET_ACCESS_KEY + # Include common retry/timeout settings + settings: !include providers/aws-settings.yaml + +Shared Zone Configuration:: + + --- + # config.yaml + zones: + example.com.: &standard-setup !include zones/standard-setup.yaml + example.net.: *standard-setup + example.org.: *standard-setup + +Zone Files +.......... + +The ``!include`` directive is particularly powerful in zone files for reducing +duplication of common record configurations. + +Shared APEX Records +~~~~~~~~~~~~~~~~~~~ + +When you have multiple zones with shared APEX records but differing records +otherwise, you can share the APEX configuration:: + + --- + # example.com.yaml + '': !include common/apex.yaml + api: + type: A + value: 1.2.3.4 + web: + type: A + value: 1.2.3.5 + +Where ``common/apex.yaml`` might contain:: + + --- + - type: A + value: 1.2.3.4 + - type: MX + values: + - exchange: mail1.example.com. + preference: 10 + - exchange: mail2.example.com. + preference: 20 + - type: NS + values: + - 6.2.3.4. + - 7.2.3.4. + - type: TXT + values: + - some-domain-claiming-value=gimme + - v=spf1 -all + +Common Record Values +~~~~~~~~~~~~~~~~~~~~ + +You can merge multiple files to build up complex record sets:: + + --- + # zone.yaml + '': + type: TXT + values: !include + - txt-records/verification.yaml + - txt-records/spf.yaml + - txt-records/dmarc.yaml + +This combines TXT records from multiple files into a single record set. + +Subdirectories +.............. + +Files in subdirectories can be included using relative paths:: + + --- + # main.yaml + nested-config: !include subdir/nested.yaml + deeper: !include subdir/another/deep.yaml + parent: !include ../sibling/config.yaml + +Type Requirements +----------------- + +When using the array syntax to include multiple files, all files must contain +compatible types: + +* All files must contain **dictionaries**, or +* All files must contain **arrays** + +If the first file contains a dictionary and a subsequent file contains an array +(or vice versa), octoDNS will raise a ``ConstructorError`` with a clear message +indicating which file and position caused the type mismatch. + +Simple scalar values (strings, numbers, booleans) are not supported with the +array syntax. Use single file includes for scalar values. + +Examples +-------- + +Example 1: Shared Provider Settings +.................................... + +Create reusable provider configurations:: + + # providers/retry-settings.yaml + --- + max_retries: 5 + retry_delay: 2 + timeout: 30 + + # production.yaml + --- + providers: + dacloud: + class: octodns_route53.DaCloudProvider + access_key_id: env/DC_ACCESS_KEY_ID + secret_access_key: env/DC_SECRET_ACCESS_KEY + network: !include providers/retry-settings.yaml + +Example 2: Composing TXT Records +................................. + +Build TXT records from multiple sources:: + + # txt-records/spf.yaml + --- + - "v=spf1 include:_spf.google.com ~all" + + # txt-records/verification.yaml + --- + - "google-site-verification=abc123" + - "ms-domain-verification=xyz789" + + # example.com.yaml + --- + '': + type: TXT + values: !include + - txt-records/spf.yaml + - txt-records/verification.yaml + +Best Practices +-------------- + +1. **Organize shared files**: Create a dedicated directory structure for shared + configurations (e.g., ``shared/``, ``common/``) + +2. **Use descriptive filenames**: Name included files clearly to indicate their + purpose (e.g., ``spf-record.yaml``, ``geo-routing-rules.yaml``) + +3. **Keep includes shallow**: Avoid deeply nested includes as they can make + the configuration harder to understand and debug + +4. **Document shared files**: Add comments in shared files explaining their + purpose and where they're used \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 983a5ca..7d9f173 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -28,6 +28,7 @@ Documentation getting-started.rst records.md configuration.rst + include_directive.rst dynamic_zone_config.rst dynamic_records.rst auto_arpa.rst