neulab/tldr huggingface dataset:
The destroy() Function This function irreversibly destroys a virtual machine on the cloud provider.  Before doing so, it should fire an event on the Salt event bus. The tag for this event is salt/cloud/<vm name>/destroying. Once the virtual machine has been destroyed, another event is fired. The tag for that event is salt/cloud/<vm name>/destroyed.
This function is normally called with the -d options:
salt-cloud -d myinstance
The list_nodes() Function This function returns a list of nodes available on this cloud provider, using the following fields:
• id (str)
• image (str)
• size (str)
• state (str)
• private_ips (list)
• public_ips (list)
No other fields should be returned in this function, and all of these fields should be returned, even if empty. The private_ips and public_ips fields should always be of a list type, even if empty, and the other fields should always be of a str type. This function is normally called with the -Q option:
salt-cloud -Q
The list_nodes_full() Function All information available about all nodes should be returned in this function.  The fields in the list_nodes() function should also be returned, even if they would not normally be provided by the cloud provider. This is because some functions both within Salt and 3rd party will break if an expected field is not present. This function is normally called with the -F option:
salt-cloud -F
The list_nodes_select() Function This function returns only the fields specified in the query.selection option in /etc/salt/cloud. Because this function is so generic, all of the heavy lifting has been moved into the salt.utils.cloud library.
A function to call list_nodes_select() still needs to be present. In general, the following code can be used as-is:
def list_nodes_select(call=None): """ Return a list of the VMs that are on the provider, with select fields """ return salt.utils.cloud.list_nodes_select( list_nodes_full("function"), __opts__["query.selection"], call )
However, depending on the cloud provider, additional variables may be required.  For instance, some modules use a conn object, or may need to pass other options into list_nodes_full(). In this case, be sure to update the function appropriately:
def list_nodes_select(conn=None, call=None): """ Return a list of the VMs that are on the provider, with select fields """ if not conn: conn = get_conn()  # pylint: disable=E0602
return salt.utils.cloud.list_nodes_select( list_nodes_full(conn, "function"), __opts__["query.selection"], call )
This function is normally called with the -S option:
salt-cloud -S
The show_instance() Function This function is used to display all of the information about a single node that is available from the cloud provider. The simplest way to provide this is usually to call list_nodes_full(), and return just the data for the requested node. It is normally called as an action:
Actions and Functions Extra functionality may be added to a cloud provider in the form of an --action or a --function. Actions are performed against a cloud instance/virtual machine, and functions are performed against a cloud provider.
Actions Actions are calls that are performed against a specific instance or virtual machine. The show_instance action should be available in all cloud modules.  Actions are normally called with the -a option:
Actions must accept a name as a first argument, may optionally support any number of kwargs as appropriate, and must accept an argument of call, with a default of None.
Before performing any other work, an action should normally verify that it has been called correctly. It may then perform the desired feature, and return useful information to the user. A basic action looks like:
def show_instance(name, call=None): """ Show the details from EC2 concerning an AMI """ if call != "action": raise SaltCloudSystemExit( "The show_instance action must be called with -a or --action." )
return _get_node(name)
Please note that generic kwargs, if used, are passed through to actions as kwargs and not **kwargs. An example of this is seen in the Functions section.
Functions Functions are called that are performed against a specific cloud provider. An optional function that is often useful is show_image, which describes an image in detail. Functions are normally called with the -f option:
salt-cloud -f show_image my-cloud-provider image='Ubuntu 13.10 64-bit'
A function may accept any number of kwargs as appropriate, and must accept an argument of call with a default of None.
Before performing any other work, a function should normally verify that it has been called correctly. It may then perform the desired feature, and return useful information to the user. A basic function looks like:
def show_image(kwargs, call=None): """ Show the details from EC2 concerning an AMI """ if call != "function": raise SaltCloudSystemExit( "The show_image action must be called with -f or --function." )
params = {"ImageId.1": kwargs["image"], "Action": "DescribeImages"} result = query(params) log.info(result)
Take note that generic kwargs are passed through to functions as kwargs and not **kwargs.
Cloud deployment scripts Salt Cloud works primarily by executing a script on the virtual machines as soon as they become available. The script that is executed is referenced in the cloud profile as the script. In older versions, this was the os argument. This was changed in 0.8.2.
A number of legacy scripts exist in the deploy directory in the saltcloud source tree. The preferred method is currently to use the salt-bootstrap script. A stable version is included with each release tarball starting with 0.8.4. The most updated version can be found at:
https://github.com/saltstack/salt-bootstrap
Note that, somewhat counter-intuitively, this script is referenced as bootstrap-salt in the configuration.
You can specify a deploy script in the cloud configuration file (/etc/salt/cloud by default):
script: bootstrap-salt
Or in a provider:
my-provider: # snip... script: bootstrap-salt
Or in a profile:
my-profile: provider: my-provider # snip... script: bootstrap-salt
If you do not specify a script argument in your cloud configuration file, provider configuration or profile configuration, the "bootstrap-salt" script will be used by default.
Other Generic Deploy Scripts If you want to be assured of always using the latest Salt Bootstrap script, there are a few generic templates available in the deploy directory of your saltcloud source tree:
curl-bootstrap curl-bootstrap-git python-bootstrap wget-bootstrap wget-bootstrap-git
These are example scripts which were designed to be customized, adapted, and refit to meet your needs. One important use of them is to pass options to the salt-bootstrap script, such as updating to specific git tags.
Custom Deploy Scripts If the Salt Bootstrap script does not meet your needs, you may write your own.  The script should be written in shell and is a Jinja template. Deploy scripts need to execute a number of functions to do a complete salt setup. These functions include:
1. Install the salt minion. If this can be done via system packages this method is HIGHLY preferred.
2. Add the salt minion keys before the minion is started for the first time.  The minion keys are available as strings that can be copied into place in the Jinja template under the dict named "vm".
3. Start the salt-minion daemon and enable it at startup time.
4. Set up the minion configuration file from the "minion" data available in the Jinja template.
A good, well commented example of this process is the Fedora deployment script:
https://github.com/saltstack/salt/blob/master/salt/cloud/deploy/Fedora.sh
A number of legacy deploy scripts are included with the release tarball. None of them are as functional or complete as Salt Bootstrap, and are still included for academic purposes.
Custom deploy scripts are picked up from /etc/salt/cloud.deploy.d by default, but you can change the location of deploy scripts with the cloud configuration deploy_scripts_search_path. Additionally, if your deploy script has the extension .sh, you can leave out the extension in your configuration.
For example, if your custom deploy script is located in /etc/salt/cloud.deploy.d/my_deploy.sh, you could specify it in a cloud profile like this:
my-profile: provider: my-provider # snip... script: my_deploy
You're also free to use the full path to the script if you like. Using full paths, your script doesn't have to live inside /etc/salt/cloud.deploy.d or whatever you've configured with deploy_scripts_search_path.
Post-Deploy Commands Once a minion has been deployed, it has the option to run a salt command. Normally, this would be the state.apply, which would finish provisioning the VM. Another common option (for testing) is to use test.version. This is configured in the main cloud config file:
start_action: state.apply
This is currently considered to be experimental functionality, and may not work well with all cloud hosts. If you experience problems with Salt Cloud hanging after Salt is deployed, consider using Startup States instead:
https://docs.saltproject.io/ref/states/startup.html
Skipping the Deploy Script For whatever reason, you may want to skip the deploy script altogether. This results in a VM being spun up much faster, with absolutely no configuration.  This can be set from the command line:
salt-cloud --no-deploy -p micro_aws my_instance
Or it can be set from the main cloud config file:
deploy: False
Or it can be set from the provider's configuration:
RACKSPACE.user: example_user RACKSPACE.apikey: 123984bjjas87034 RACKSPACE.deploy: False
Or even on the VM's profile settings:
ubuntu_aws: provider: my-ec2-config image: ami-7e2da54e size: t1.micro deploy: False
The default for deploy is True.
In the profile, you may also set the script option to None:
script: None
This is the slowest option, since it still uploads the None deploy script and executes it.
Updating Salt Bootstrap Salt Bootstrap can be updated automatically with salt-cloud:
salt-cloud -u salt-cloud --update-bootstrap
Bear in mind that this updates to the latest stable version from:
https://bootstrap.saltstack.com/stable/bootstrap-salt.sh
To update Salt Bootstrap script to the develop version, run the following command on the Salt minion host with salt-cloud installed:
salt-call config.gather_bootstrap_script 'https://bootstrap.saltstack.com/develop/bootstrap-salt.sh'
Or just download the file manually:
curl -L 'https://bootstrap.saltstack.com/develop' > /etc/salt/cloud.deploy.d/bootstrap-salt.sh
aws-amazon: provider: my-ec2-config image: ami-1624987f size: t1.micro ssh_username: ec2-user script: bootstrap-salt script_args: -c /tmp/
Using Salt Cloud from Salt Using the Salt Modules for Cloud In addition to the salt-cloud command, Salt Cloud can be called from Salt, in a variety of different ways. Most users will be interested in either the execution module or the state module, but it is also possible to call Salt Cloud as a runner.
Because the actual work will be performed on a remote minion, the normal Salt Cloud configuration must exist on any target minion that needs to execute a Salt Cloud command.  Because Salt Cloud now supports breaking out configuration into individual files, the configuration is easily managed using Salt's own file.managed state function. For example, the following directories allow this configuration to be managed easily:
/etc/salt/cloud.providers.d/ /etc/salt/cloud.profiles.d/
Minion Keys Keep in mind that when creating minions, Salt Cloud will create public and private minion keys, upload them to the minion, and place the public key on the machine that created the minion. It will not attempt to place any public minion keys on the master, unless the minion which was used to create the instance is also the Salt Master. This is because granting arbitrary minions access to modify keys on the master is a serious security risk, and must be avoided.
Execution Module The cloud module is available to use from the command line. At the moment, almost every standard Salt Cloud feature is available to use. The following commands are available:
list_images This command is designed to show images that are available to be used to create an instance using Salt Cloud. In general they are used in the creation of profiles, but may also be used to create an instance directly (see below).  Listing images requires a provider to be configured, and specified:
salt myminion cloud.list_images my-cloud-provider
list_sizes This command is designed to show sizes that are available to be used to create an instance using Salt Cloud. In general they are used in the creation of profiles, but may also be used to create an instance directly (see below). This command is not available for all cloud providers; see the provider-specific documentation for details. Listing sizes requires a provider to be configured, and specified:
salt myminion cloud.list_sizes my-cloud-provider
list_locations This command is designed to show locations that are available to be used to create an instance using Salt Cloud. In general they are used in the creation of profiles, but may also be used to create an instance directly (see below). This command is not available for all cloud providers; see the provider-specific documentation for details. Listing locations requires a provider to be configured, and specified:
salt myminion cloud.list_locations my-cloud-provider
query This command is used to query all configured cloud providers, and display all instances associated with those accounts. By default, it will run a standard query, returning the following fields:
id     The name or ID of the instance, as used by the cloud provider.
image  The disk image that was used to create this instance.
private_ips Any public IP addresses currently assigned to this instance.
public_ips Any private IP addresses currently assigned to this instance.
size   The size of the instance; can refer to RAM, CPU(s), disk space, etc., depending on the cloud provider.
state  The running state of the instance; for example, running, stopped, pending, etc. This state is dependent upon the provider.
This command may also be used to perform a full query or a select query, as described below. The following usages are available:
salt myminion cloud.query salt myminion cloud.query list_nodes salt myminion cloud.query list_nodes_full
full_query This command behaves like the query command, but lists all information concerning each instance as provided by the cloud provider, in addition to the fields returned by the query command.
salt myminion cloud.full_query
select_query This command behaves like the query command, but only returned select fields as defined in the /etc/salt/cloud configuration file. A sample configuration for this section of the file might look like:
query.selection: - id - key_name
This configuration would only return the id and key_name fields, for those cloud providers that support those two fields. This would be called using the following command:
salt myminion cloud.select_query
profile This command is used to create an instance using a profile that is configured on the target minion. Please note that the profile must be configured before this command can be used with it.
salt myminion cloud.profile ec2-centos64-x64 my-new-instance
Please note that the execution module does not run in parallel mode. Using multiple minions to create instances can effectively perform parallel instance creation.
create This command is similar to the profile command, in that it is used to create a new instance. However, it does not require a profile to be pre-configured.  Instead, all of the options that are normally configured in a profile are passed directly to Salt Cloud to create the instance:
salt myminion cloud.create my-ec2-config my-new-instance \ image=ami-1624987f size='t1.micro' ssh_username=ec2-user \ securitygroup=default delvol_on_destroy=True
destroy This command is used to destroy an instance or instances. This command will search all configured providers and remove any instance(s) which matches the name(s) passed in here. The results of this command are non-reversable and should be used with caution.
salt myminion cloud.destroy myinstance salt myminion cloud.destroy myinstance1,myinstance2
action This command implements both the action and the function commands used in the standard salt-cloud command. If one of the standard action commands is used, an instance name must be provided. If one of the standard function commands is used, a provider configuration must be named.
salt myminion cloud.action start instance=myinstance salt myminion cloud.action show_image provider=my-ec2-config \ image=ami-1624987f
The actions available are largely dependent upon the module for the specific cloud provider. The following actions are available for all cloud providers:
list_nodes This is a direct call to the query function as described above, but is only performed against a single cloud provider. A provider configuration must be included.
list_nodes_select This is a direct call to the full_query function as described above, but is only performed against a single cloud provider. A provider configuration must be included.
list_nodes_select This is a direct call to the select_query function as described above, but is only performed against a single cloud provider.  A provider configuration must be included.
show_instance This is a thin wrapper around list_nodes, which returns the full information about a single instance. An instance name must be provided.
State Module A subset of the execution module is available through the cloud state module. Not all functions are currently included, because there is currently insufficient code for them to perform statefully. For example, a command to create an instance may be issued with a series of options, but those options cannot currently be statefully managed. Additional states to manage these options will be released at a later time.
cloud.present This state will ensure that an instance is present inside a particular cloud provider. Any option that is normally specified in the cloud.create execution module and function may be declared here, but only the actual presence of the instance will be managed statefully.
my-instance-name: cloud.present: - cloud_provider: my-ec2-config - image: ami-1624987f - size: 't1.micro' - ssh_username: ec2-user - securitygroup: default - delvol_on_destroy: True
cloud.profile This state will ensure that an instance is present inside a particular cloud provider. This function calls the cloud.profile execution module and function, but as with cloud.present, only the actual presence of the instance will be managed statefully.
my-instance-name: cloud.profile: - profile: ec2-centos64-x64
cloud.absent This state will ensure that an instance (identified by name) does not exist in any of the cloud providers configured on the target minion. Please note that this state is non-reversable and may be considered especially destructive when issued as a cloud state.
my-instance-name: cloud.absent
Runner Module The cloud runner module is executed on the master, and performs actions using the configuration and Salt modules on the master itself. This means that any public minion keys will also be properly accepted by the master.
Using the functions in the runner module is no different than using those in the execution module, outside of the behavior described in the above paragraph.  The following functions are available inside the runner:
• list_images
• list_sizes
• list_locations
• query
• full_query
• select_query
• profile
• destroy
• action
Outside of the standard usage of salt-run itself, commands are executed as usual:
salt-run cloud.profile ec2-centos64-x86_64 my-instance-name
CloudClient The execution, state, and runner modules ultimately all use the CloudClient library that ships with Salt. To use the CloudClient library locally (either on the master or a minion), create a client object and issue a command against it:
import salt.cloud import pprint
client = salt.cloud.CloudClient("/etc/salt/cloud") nodes = client.query() pprint.pprint(nodes)
Reactor Examples of using the reactor with Salt Cloud are available in the ec2-autoscale-reactor and salt-cloud-reactor formulas.
Feature Comparison Feature Matrix A number of features are available in most cloud hosts, but not all are available everywhere. This may be because the feature isn't supported by the cloud host itself, or it may only be that the feature has not yet been added to Salt Cloud. In a handful of cases, it is because the feature does not make sense for a particular cloud provider (Saltify, for instance).
This matrix shows which features are available in which cloud hosts, as far as Salt Cloud is concerned. This is not a comprehensive list of all features available in all cloud hosts, and should not be used to make business decisions concerning choosing a cloud host. In most cases, adding support for a feature to Salt Cloud requires only a little effort.
Legacy Drivers Both AWS and Rackspace are listed as "Legacy". This is because those drivers have been replaced by other drivers, which are generally the preferred method for working with those hosts.
The EC2 driver should be used instead of the AWS driver, when possible. The OpenStack driver should be used instead of the Rackspace driver, unless the user is dealing with instances in "the old cloud" in Rackspace.
Note for Developers When adding new features to a particular cloud host, please make sure to add the feature to this table. Additionally, if you notice a feature that is not properly listed here, pull requests to fix them is appreciated.
Standard Features These are features that are available for almost every cloud host.
┌──────────┬──────────┬────────────┬─────────┬─────┬────────┬────────┬────────┬───────────┬───────────┬───────────┬─────────┬─────────┬───────────┬───────────┬────────┬─────────┐
│          │ AWS      │ CloudStack │ Digital │ EC2 │ GoGrid │ JoyEnt │ Linode │ OpenStack │ Parallels │ Rackspace │ Saltify │ Vagrant │ Softlayer │ Softlayer │ Aliyun │ Tencent │
│          │ (Legacy) │            │ Ocean   │     │        │        │        │           │           │ (Legacy)  │         │         │           │ Hardware  │        │ Cloud   │
├──────────┼──────────┼────────────┼─────────┼─────┼────────┼────────┼────────┼───────────┼───────────┼───────────┼─────────┼─────────┼───────────┼───────────┼────────┼─────────┤
│Query     │ Yes      │ Yes        │ Yes     │ Yes │ Yes    │ Yes    │ Yes    │ Yes       │ Yes       │ Yes       │ [1]     │ [1]     │ Yes       │ Yes       │ Yes    │ Yes     │
└──────────┴──────────┴────────────┴─────────┴─────┴────────┴────────┴────────┴───────────┴───────────┴───────────┴─────────┴─────────┴───────────┴───────────┴────────┴─────────┘
[1] Yes, if salt-api is enabled.
[2] Always returns {}.
Actions These are features that are performed on a specific instance, and require an instance name to be passed in. For example:
# salt-cloud -a attach_volume ami.example.com
Tutorials Salt Cloud Quickstart Salt Cloud is built-in to Salt, and the easiest way to run Salt Cloud is directly from your Salt Master.
This quickstart walks you through the basic steps of setting up a cloud host and defining some virtual machines to create.
NOTE: Salt Cloud has its own process and does not rely on the Salt Master, so it can be installed on a standalone minion instead of your Salt Master.
Define a Provider The first step is to add the credentials for your cloud host. Credentials and other settings provided by the cloud host are stored in provider configuration files. Provider configurations contain the details needed to connect to a cloud host such as EC2, GCE, Rackspace, etc., and any global options that you want set on your cloud minions (such as the location of your Salt Master).
On your Salt Master, browse to /etc/salt/cloud.providers.d/ and create a file called <provider>.conf, replacing <provider> with ec2, softlayer, and so on. The name helps you identify the contents, and is not important as long as the file ends in .conf.
Next, browse to the Provider specifics and add any required settings for your cloud host to this file. Here is an example for Amazon EC2:
my-ec2: driver: ec2 # Set the EC2 access credentials (see below) # id: 'HJGRYCILJLKJYG' key: 'kdjgfsgm;woormgl/aserigjksjdhasdfgn' # Make sure this key is owned by root with permissions 0400. # private_key: /etc/salt/my_test_key.pem keyname: my_test_key securitygroup: default # Optional: Set up the location of the Salt Master # minion: master: saltmaster.example.com
The required configuration varies between cloud hosts so make sure you read the provider specifics.
List Cloud Provider Options You can now query the cloud provider you configured for available locations, images, and sizes. This information is used when you set up VM profiles.
salt-cloud --list-locations <provider_name>  # my-ec2 in the previous example salt-cloud --list-images <provider_name> salt-cloud --list-sizes <provider_name>
Replace <provider_name> with the name of the provider configuration you defined.
Create VM Profiles On your Salt Master, browse to /etc/salt/cloud.profiles.d/ and create a file called <profile>.conf, replacing <profile> with ec2, softlayer, and so on. The file must end in .conf.
You can now add any custom profiles you'd like to define to this file. Here are a few examples:
micro_ec2: provider: my-ec2 image: ami-d514f291 size: t1.micro
medium_ec2: provider: my-ec2 image: ami-d514f291 size: m3.medium
large_ec2: provider: my-ec2 image: ami-d514f291 size: m3.large
Notice that the provider in our profile matches the provider name that we defined? That is how Salt Cloud knows how to connect to a cloud host to create a VM with these attributes.
Create VMs VMs are created by calling salt-cloud with the following options:
salt-cloud -p <profile> <name1> <name2> ...
salt-cloud -p micro_ec2 minion1 minion2
Destroy VMs Add a -d and the minion name you provided to destroy:
salt-cloud -d minion1 minion2
Query VMs You can view details about the VMs you've created using --query:
salt-cloud --query
Cloud Map Now that you know how to create and destoy individual VMs, next you should learn how to use a cloud map to create a number of VMs at once.
Cloud maps let you define a map of your infrastructure and quickly provision any number of VMs. On subsequent runs, any VMs that do not exist are created, and VMs that are already configured are left unmodified.
See Cloud Map File.
Using Salt Cloud with the Event Reactor One of the most powerful features of the Salt framework is the Event Reactor.  As the Reactor was in development, Salt Cloud was regularly updated to take advantage of the Reactor upon completion. As such, various aspects of both the creation and destruction of instances with Salt Cloud fire events to the Salt Master, which can be used by the Event Reactor.
Event Structure As of this writing, all events in Salt Cloud have a tag, which includes the ID of the instance being managed, and a payload which describes the task that is currently being handled. A Salt Cloud tag looks like:
salt/cloud/<minion_id>/<task>
For instance, the first event fired when creating an instance named web1 would look like:
salt/cloud/web1/creating
Assuming this instance is using the ec2-centos profile, which is in turn using the ec2-config provider, the payload for this tag would look like:
{"name": "web1", "profile": "ec2-centos", "provider": "ec2-config:ec2"}
Available Events When an instance is created in Salt Cloud, whether by map, profile, or directly through an API, a minimum of five events are normally fired. More may be available, depending upon the cloud provider being used. Some of the common events are described below.
salt/cloud/<minion_id>/creating This event states simply that the process to create an instance has begun. At this point in time, no actual work has begun. The payload for this event includes:
name profile provider
salt/cloud/<minion_id>/requesting Salt Cloud is about to make a request to the cloud provider to create an instance. At this point, all of the variables required to make the request have been gathered, and the payload of the event will reflect those variables which do not normally pose a security risk. What is returned here is dependent upon the cloud provider. Some common variables are:
name image size location
salt/cloud/<minion_id>/querying The instance has been successfully requested, but the necessary information to log into the instance (such as IP address) is not yet available. This event marks the beginning of the process to wait for this information.
The payload for this event normally only includes the instance_id.
salt/cloud/<minion_id>/waiting_for_ssh The information required to log into the instance has been retrieved, but the instance is not necessarily ready to be accessed. Following this event, Salt Cloud will wait for the IP address to respond to a ping, then wait for the specified port (usually 22) to respond to a connection, and on Linux systems, for SSH to become available. Salt Cloud will attempt to issue the date command on the remote system, as a means to check for availability. If no ssh_username has been specified, a list of usernames (starting with root) will be attempted. If one or more usernames was configured for ssh_username, they will be added to the beginning of the list, in order.
The payload for this event normally only includes the ip_address.
salt/cloud/<minion_id>/deploying The necessary port has been detected as available, and now Salt Cloud can log into the instance, upload any files used for deployment, and run the deploy script. Once the script has completed, Salt Cloud will log back into the instance and remove any remaining files.
A number of variables are used to deploy instances, and the majority of these will be available in the payload. Any keys, passwords or other sensitive data will be scraped from the payload. Most of the variables returned will be related to the profile or provider config, and any default values that could have been changed in the profile or provider, but weren't.
salt/cloud/<minion_id>/created The deploy sequence has completed, and the instance is now available, Salted, and ready for use. This event is the final task for Salt Cloud, before returning instance information to the user and exiting.
The payload for this event contains little more than the initial creating event. This event is required in all cloud providers.
Filtering Events When creating a VM, it is possible with certain tags to filter how much information is sent to the event bus. The tags that can be filtered on any provider are:
• salt/cloud/<minion_id>/creating
• salt/cloud/<minion_id>/requesting
• salt/cloud/<minion_id>/created
Other providers may allow other tags to be filtered; when that is the case, the documentation for that provider will contain more details.
To filter information, create a section in your /etc/salt/cloud file called filter_events. Create a section for each tag that you want to filter, using the last segment of the tag. For instance, use creating to represent salt/cloud/<minion_id>/creating:
filter_events: creating: keys: - name - profile - provider
Any keys listed here will be added to the default keys that are already set to be displayed for that provider. If you wish to start with a clean slate and only show the keys specified, add another option called use_defaults and set it to False.
filter_events: creating: keys: - name - profile - provider use_defaults: False
Configuring the Event Reactor The Event Reactor is built into the Salt Master process, and as such is configured via the master configuration file. Normally this will be a YAML file located at /etc/salt/master. Additionally, master configuration items can be stored, in YAML format, inside the /etc/salt/master.d/ directory.
These configuration items may be stored in either location; however, they may only be stored in one location. For organizational and security purposes, it may be best to create a single configuration file, which contains only Event Reactor configuration, at /etc/salt/master.d/reactor.
The Event Reactor uses a top-level configuration item called reactor. This block contains a list of tags to be watched for, each of which also includes a list of sls files. For instance:
reactor: - 'salt/minion/*/start': - '/srv/reactor/custom-reactor.sls' - 'salt/cloud/*/created': - '/srv/reactor/cloud-alert.sls' - 'salt/cloud/*/destroyed': - '/srv/reactor/cloud-destroy-alert.sls'
The above configuration configures reactors for three different tags: one which is fired when a minion process has started and is available to receive commands, one which is fired when a cloud instance has been created, and one which is fired when a cloud instance is destroyed.
Note that each tag contains a wildcard (*) in it. For each of these tags, this will normally refer to a minion_id. This is not required of event tags, but is very common.
Reactor SLS Files Reactor sls files should be placed in the /srv/reactor/ directory for consistency between environments, but this is not currently enforced by Salt.
Reactor sls files follow a similar format to other sls files in Salt. By default they are written in YAML and can be templated using Jinja, but since they are processed through Salt's rendering system, any available renderer (JSON, Mako, Cheetah, etc.) can be used.
As with other sls files, each stanza will start with a declaration ID, followed by the function to run, and then any arguments for that function. For example:
# /srv/reactor/cloud-alert.sls new_instance_alert: cmd.pagerduty.create_event: - tgt: alertserver - kwarg: description: "New instance: {{ data['name'] }}" details: "New cloud instance created on {{ data['provider'] }}" service_key: 1626dead5ecafe46231e968eb1be29c4 profile: my-pagerduty-account
When the Event Reactor receives an event notifying it that a new instance has been created, this sls will create a new incident in PagerDuty, using the configured PagerDuty account.
The declaration ID in this example is new_instance_alert. The function called is cmd.pagerduty.create_event. The cmd portion of this function specifies that an execution module and function will be called, in this case, the pagerduty.create_event function.
Because an execution module is specified, a target (tgt) must be specified on which to call the function. In this case, a minion called alertserver has been used. Any arguments passed through to the function are declared in the kwarg block.
Example: Reactor-Based Highstate When Salt Cloud creates an instance, by default it will install the Salt Minion onto the instance, along with any specified minion configuration, and automatically accept that minion's keys on the master. One of the configuration options that can be specified is startup_states, which is commonly set to highstate. This will tell the minion to immediately apply a highstate, as soon as it is able to do so.
This can present a problem with some system images on some cloud hosts. For instance, Salt Cloud can be configured to log in as either the root user, or a user with sudo access. While some hosts commonly use images that lock out remote root access and require a user with sudo privileges to log in (notably EC2, with their ec2-user login), most cloud hosts fall back to root as the default login on all images, including for operating systems (such as Ubuntu) which normally disallow remote root login.
For users of these operating systems, it is understandable that a highstate would include configuration to block remote root logins again. However, Salt Cloud may not have finished cleaning up its deployment files by the time the minion process has started, and kicked off a highstate run. Users have reported errors from Salt Cloud getting locked out while trying to clean up after itself.
The goal of a startup state may be achieved using the Event Reactor. Because a minion fires an event when it is able to receive commands, this event can effectively be used inside the reactor system instead. The following will point the reactor system to the right sls file:
reactor: - 'salt/cloud/*/created': - '/srv/reactor/startup_highstate.sls'
And the following sls file will start a highstate run on the target minion:
# /srv/reactor/startup_highstate.sls reactor_highstate: cmd.state.apply: - tgt: {{ data['name'] }}
Because this event will not be fired until Salt Cloud has cleaned up after itself, the highstate run will not step on salt-cloud's toes. And because every file on the minion is configurable, including /etc/salt/minion, the startup_states can still be configured for future minion restarts, if desired.
Proxy minions are a developing Salt feature that enables controlling devices that, for whatever reason, cannot run a standard salt-minion. Examples include network gear that has an API but runs a proprietary OS, devices with limited CPU or memory, or devices that could run a minion, but for security reasons, will not.
There are some proxy modules available, but if your device interface is not currently supported you will most likely have to write the interface yourself, because there are an infinite number of controllable devices. Fortunately, this is only as difficult as the actual interface to the proxied device. Devices that have an existing Python module (PyUSB for example) would be relatively simple to interface.  Code to control a device that has an HTML REST-based interface should be easy.  Code to control your typical housecat would be excellent source material for a PhD thesis.
Salt proxy-minions provide the 'plumbing' that allows device enumeration and discovery, control, status, remote execution, and state management.
See the Proxy Minion Walkthrough for an end-to-end demonstration of a working REST-based proxy minion.
See the Proxy Minion SSH Walkthrough for an end-to-end demonstration of a working SSH proxy minion.
See Proxyminion States to configure and run salt-proxy on a remote minion. Specify all your master side proxy (pillar) configuration and use this state to remotely configure proxies on one or more minions.
See Proxyminion Beacon to help with easy configuration and management of salt-proxy processes.
New in 2017.7.0 The proxy_merge_grains_in_module configuration variable introduced in 2016.3, has been changed, defaulting to True.
The connection with the remote device is kept alive by default, when the module implements the alive function and proxy_keep_alive is set to True. The polling interval is set using the proxy_keep_alive_interval option which defaults to 1 minute.
The developers are also able to use the proxy_always_alive, when designing a proxy module flexible enough to open the connection with the remote device only when required.
New in 2016.11.0 Proxy minions now support configuration files with names ending in '*.conf' and placed in /etc/salt/proxy.d.
Proxy minions can now be configured in /etc/salt/proxy or /etc/salt/proxy.d instead of just pillar.  Configuration format is the same as it would be in pillar.
New in 2016.3 The deprecated config option enumerate_proxy_minions has been removed.
As mentioned in earlier documentation, the add_proxymodule_to_opts configuration variable defaults to False in this release.  This means if you have proxymodules or other code looking in __opts__['proxymodule'] you will need to set this variable in your /etc/salt/proxy file, or modify your code to use the __proxy__ injected variable.
The __proxyenabled__ directive now only applies to grains and proxy modules themselves.  Standard execution modules and state modules are not prevented from loading for proxy minions.
Enhancements in grains processing have made the __proxyenabled__ directive somewhat redundant in dynamic grains code.  It is still required, but best practices for the __virtual__ function in grains files have changed.  It is now recommended that the __virtual__ functions check to make sure they are being loaded for the correct proxytype, example below:
def __virtual__(): """ Only work on proxy """ try: if ( salt.utils.platform.is_proxy() and __opts__["proxy"]["proxytype"] == "ssh_sample" ): return __virtualname__ except KeyError: pass
The try/except block above exists because grains are processed very early in the proxy minion startup process, sometimes earlier than the proxy key in the __opts__ dictionary is populated.
Grains are loaded so early in startup that no dunder dictionaries are present, so __proxy__, __salt__, etc. are not available.  Custom grains located in /srv/salt/_grains and in the salt install grains directory can now take a single argument, proxy, that is identical to __proxy__.  This enables patterns like
def get_ip(proxy): """ Ask the remote device what IP it has """ return {"ip": proxy["proxymodulename.get_ip"]()}
Then the grain ip will contain the result of calling the get_ip() function in the proxymodule called proxymodulename.
Proxy modules now benefit from including a function called initialized(). This function should return True if the proxy's init() function has been successfully called.  This is needed to make grains processing easier.
Finally, if there is a function called grains in the proxymodule, it will be executed on proxy-minion startup and its contents will be merged with the rest of the proxy's grains.  Since older proxy-minions might have used other methods to call such a function and add its results to grains, this is config-gated by a new proxy configuration option called proxy_merge_grains_in_module.  This defaults to True in the 2017.7.0 release.
New in 2015.8.2 BREAKING CHANGE: Adding the proxymodule variable  to __opts__ is deprecated.  The proxymodule variable has been moved a new globally-injected variable called __proxy__.  A related configuration option called add_proxymodule_to_opts has been added and defaults to True.  In the next major release, 2016.3.0, this variable will default to False.
In the meantime, proxies that functioned under 2015.8.0 and .1 should continue to work under 2015.8.2.  You should rework your proxy code to use __proxy__ as soon as possible.
The rest_sample example proxy minion has been updated to use __proxy__.
This change was made because proxymodules are a LazyLoader object, but LazyLoaders cannot be serialized.  __opts__ gets serialized, and so things like saltutil.sync_all and state.highstate would throw exceptions.
Support has been added to Salt's loader allowing custom proxymodules to be placed in salt://_proxy.  Proxy minions that need these modules will need to be restarted to pick up any changes.  A corresponding utility function, saltutil.sync_proxymodules, has been added to sync these modules to minions.
In addition, a salt.utils helper function called is_proxy() was added to make it easier to tell when the running minion is a proxy minion. NOTE: This function was renamed to salt.utils.platform.is_proxy() for the 2018.3.0 release
New in 2015.8 Starting with the 2015.8 release of Salt, proxy processes are no longer forked off from a controlling minion.  Instead, they have their own script salt-proxy which takes mostly the same arguments that the standard Salt minion does with the addition of --proxyid.  This is the id that the salt-proxy will use to identify itself to the master.  Proxy configurations are still best kept in Pillar and their format has not changed.
This change allows for better process control and logging.  Proxy processes can now be listed with standard process management utilities (ps from the command line).  Also, a full Salt minion is no longer required (though it is still strongly recommended) on machines hosting proxies.
Getting Started The following diagram may be helpful in understanding the structure of a Salt installation that includes proxy-minions: [image]
The key thing to remember is the left-most section of the diagram. Salt's nature is to have a minion connect to a master, then the master may control the minion.  However, for proxy minions, the target device cannot run a minion.
After the proxy minion is started and initiates its connection to the device, it connects back to the salt-master and for all intents and purposes looks like just another minion to the Salt master.
To create support for a proxied device one needs to create four things:
1. The proxy_connection_module (located in salt/proxy).
2. The grains support code (located in salt/grains).
3. Salt modules specific to the controlled device.
4. Salt states specific to the controlled device.
Configuration parameters Proxy minions require no configuration parameters in /etc/salt/master.
Salt's Pillar system is ideally suited for configuring proxy-minions (though they can be configured in /etc/salt/proxy as well).  Proxies can either be designated via a pillar file in pillar_roots, or through an external pillar.  External pillars afford the opportunity for interfacing with a configuration management system, database, or other knowledgeable system that that may already contain all the details of proxy targets. To use static files in pillar_roots, pattern your files after the following examples, which are based on the diagram above:
base: net-device1: - net-device1 net-device2: - net-device2 net-device3: - net-device3 i2c-device4: - i2c-device4 i2c-device5: - i2c-device5 433wireless-device6: - 433wireless-device6 smsgate-device7: - device7
/srv/pillar/net-device1.sls
proxy: proxytype: networkswitch host: 172.23.23.5 username: root passwd: letmein
/srv/pillar/net-device2.sls
proxy: proxytype: networkswitch host: 172.23.23.6 username: root passwd: letmein
/srv/pillar/net-device3.sls
proxy: proxytype: networkswitch host: 172.23.23.7 username: root passwd: letmein
/srv/pillar/i2c-device4.sls
proxy: proxytype: i2c_lightshow i2c_address: 1
/srv/pillar/i2c-device5.sls
proxy: proxytype: i2c_lightshow i2c_address: 2
/srv/pillar/433wireless-device6.sls
proxy: proxytype: 433mhz_wireless
/srv/pillar/smsgate-device7.sls
proxy: proxytype: sms_serial deventry: /dev/tty04
Note the contents of each minioncontroller key may differ widely based on the type of device that the proxy-minion is managing.
In the above example
• net-devices 1, 2, and 3 are network switches that have a management interface available at a particular IP address.
• i2c-devices 4 and 5 are very low-level devices controlled over an i2c bus.  In this case the devices are physically connected to machine 'minioncontroller2', and are addressable on the i2c bus at their respective i2c addresses.
• 433wireless-device6 is a 433 MHz wireless transmitter, also physically connected to minioncontroller2
• smsgate-device7 is an SMS gateway connected to machine minioncontroller3 via a serial port.
Because of the way pillar works, each of the salt-proxy processes that fork off the proxy minions will only see the keys specific to the proxies it will be handling.
Proxies can be configured in /etc/salt/proxy or with files in /etc/salt/proxy.d as of Salt's 2016.11.0 release.
Also, in general, proxy-minions are lightweight, so the machines that run them could conceivably control a large number of devices.  To run more than one proxy from a single machine, simply start an additional proxy process with --proxyid set to the id to which you want the proxy to bind. It is possible for the proxy services to be spread across many machines if necessary, or intentionally run on machines that need to control devices because of some physical interface (e.g. i2c and serial above). Another reason to divide proxy services might be security.  In more secure environments only certain machines may have a network path to certain devices.
Proxymodules A proxy module encapsulates all the code necessary to interface with a device.  Proxymodules are located inside the salt.proxy module, or can be placed in the _proxy directory in your file_roots (default is /srv/salt/_proxy.  At a minimum a proxymodule object must implement the following functions:
__virtual__(): This function performs the same duty that it does for other types of Salt modules.  Logic goes here to determine if the module can be loaded, checking for the presence of Python modules on which the proxy depends.  Returning False will prevent the module from loading.
init(opts): Perform any initialization that the device needs.  This is a good place to bring up a persistent connection to a device, or authenticate to create a persistent authorization token.
initialized(): Returns True if init() was successfully called.
shutdown(): Code to cleanly shut down or close a connection to a controlled device goes here.  This function must exist, but can contain only the keyword pass if there is no shutdown logic required.
ping(): While not required, it is highly recommended that this function also be defined in the proxymodule. The code for ping should contact the controlled device and make sure it is really available.