Network Config

Manage the configuration on a network device given a specific static config or template.

codeauthor:Mircea Ulinic <> & Jerome Fleury <>


New in version 2017.7.0.

salt.states.netconfig.managed(name, template_name, template_source=None, template_path=None, template_hash=None, template_hash_name=None, template_user='root', template_group='root', template_mode='755', saltenv=None, template_engine='jinja', skip_verify=False, defaults=None, test=False, commit=True, debug=False, replace=False, **template_vars)

Manages the configuration on network devices.

By default this state will commit the changes on the device. If there are no changes required, it does not commit and the field already_configured from the output dictionary will be set as True to notify that.

To avoid committing the configuration, set the argument test to True (or via the CLI argument test=True) and will discard (dry run).

To preserve the changes, set commit to False (either as CLI argument, either as state parameter). However, this is recommended to be used only in exceptional cases when there are applied few consecutive states and/or configuration changes. Otherwise the user might forget that the config DB is locked and the candidate config buffer is not cleared/merged in the running config.

To replace the config, set replace to True. This option is recommended to be used with caution!


The support for NAPALM native templates will be dropped beginning with Salt Fluorine. Implicitly, the template_path argument will be deprecated and removed.


Identifies path to the template source. The template can be either stored on the local machine, either remotely. The recommended location is under the file_roots as specified in the master config file. For example, let's suppose the file_roots is configured as:

        - /etc/salt/states

Placing the template under /etc/salt/states/templates/example.jinja, it can be used as salt://templates/example.jinja. Alternatively, for local files, the user can specify the absolute path. If remotely, the source can be retrieved via http, https or ftp.


  • salt://my_template.jinja
  • /absolute/path/to/my_template.jinja
  • https:/
template_source: None
Inline config template to be rendered and loaded on the device.
template_path: None
Required only in case the argument template_name provides only the file basename. E.g.: if template_name is specified as my_template.jinja, in order to find the template, this argument must be provided: template_path: /absolute/path/to/.
template_hash: None
Hash of the template file. Format: {hash_type: 'md5', 'hsum': <md5sum>}
template_hash_name: None
When template_hash refers to a remote file, this specifies the filename to look for in that file.
template_group: root
Owner of file.
template_user: root
Group owner of file.
template_user: 755
Permissions of file
saltenv: base
Specifies the template environment. This will influence the relative imports inside the templates.
template_engine: jinja

The following templates engines are supported:

skip_verify: False

If True, hash verification of remote file sources (http://, https://, ftp://) will be skipped, and the source_hash argument will be ignored.

Changed in version 2017.7.1.

test: False
Dry run? If set to True, will apply the config, discard and return the changes. Default: False (will commit the changes on the device).
commit: True
Commit? Default: True.
debug: False

Debug mode. Will insert a new key under the output dictionary, as loaded_config containing the raw result after the template was rendered.


This argument cannot be used directly on the command line. Instead, it can be passed through the pillar variable when executing either of the state.sls or state.apply (see below for an example).

replace: False
Load and replace the configuration. Default: False (will apply load merge).
defaults: None
Default variables/context passed to the template.
Dictionary with the arguments/context to be used when the template is rendered. Do not explicitly specify this argument. This represents any other variable that will be sent to the template rendering system. Please see an example below! In both ntp_peers_example_using_pillar and ntp_peers_example, peers is sent as template variable.

SLS Example (e.g.: under salt://router/config.sls) :

        - template_name: salt://path/to/complete_config.jinja
        - debug: True
        - replace: True
        - template_name: /absolute/path/to/bgp_neighbors.mako
        - template_engine: mako
        - template_name: prefix_lists.cheetah
        - template_path: /absolute/path/to/
        - debug: True
        - template_engine: cheetah
        - template_name:
        - skip_verify: False
        - debug: True
        - peers:
        - template_name:
        - peers: {{ pillar.get('ntp.peers', []) }}

Usage examples:

$ sudo salt 'juniper.device' state.sls router.config test=True

$ sudo salt -N all-routers state.sls router.config pillar="{'debug': True}"

router.config depends on the location of the SLS file (see above). Running this command, will be executed all five steps from above. These examples above are not meant to be used in a production environment, their sole purpose is to provide usage examples.

Output example:

$ sudo salt 'juniper.device' state.sls router.config test=True
          ID: ntp_peers_example_using_pillar
    Function: netconfig.managed
      Result: None
     Comment: Testing mode: Configuration discarded.
     Started: 12:01:40.744535
    Duration: 8755.788 ms
                  [edit system ntp]
                       peer { ... }
                  +    peer;
                  +    peer;

Summary for juniper.device
Succeeded: 1 (unchanged=1, changed=1)
Failed:    0
Total states run:     1
Total run time:   8.756 s

Raw output example (useful when the output is reused in other states/execution modules):

$ sudo salt --out=pprint 'juniper.device' state.sls router.config test=True debug=True
    'juniper.device': {
        'netconfig_|-ntp_peers_example_using_pillar_|-ntp_peers_example_using_pillar_|-managed': {
            '__id__': 'ntp_peers_example_using_pillar',
            '__run_num__': 0,
            'already_configured': False,
            'changes': {
                'diff': '[edit system ntp]   peer { ... }+   peer;+   peer;'
            'comment': 'Testing mode: Configuration discarded.',
            'duration': 7400.759,
            'loaded_config': 'system {  ntp {  peer;  peer; } }',
            'name': 'ntp_peers_example_using_pillar',
            'result': None,
            'start_time': '12:09:09.811445'