# Buggy code
def minion_config(opts, vm_):
    """
    Return a minion's configuration for the provided options and VM
    """

    # Let's get a copy of the salt minion default options
    minion = copy.deepcopy(salt.config.DEFAULT_MINION_OPTS)
    # Some default options are Null, let's set a reasonable default
    minion.update(log_level="info", log_level_logfile="info", hash_type="sha256")

    # Now, let's update it to our needs
    minion["id"] = vm_["name"]
    master_finger = salt.config.get_cloud_config_value("master_finger", vm_, opts)
    if master_finger is not None:
        minion["master_finger"] = master_finger
    minion.update(
        # Get ANY defined minion settings, merging data, in the following order
        # 1. VM config
        # 2. Profile config
        # 3. Global configuration
        salt.config.get_cloud_config_value(
            "minion", vm_, opts, default={}, search_global=True
        )
    )

    make_master = salt.config.get_cloud_config_value("make_master", vm_, opts)
    if "master" not in minion and make_master is not True:
        raise SaltCloudConfigError(
            "A master setting was not defined in the minion's configuration."
        )

    # Get ANY defined grains settings, merging data, in the following order
    # 1. VM config
    # 2. Profile config
    # 3. Global configuration
    minion.setdefault("grains", {}).update(
        salt.config.get_cloud_config_value(
            "grains", vm_, opts, default={}, search_global=True
        )
    )
    return minion


# Traceback (ParserError)
li1105-12 ~ master # salt jmoney-master state.show_top
jmoney-master:
The minion function caused an exception: Traceback (most recent call last):
File "/root/salt/salt/minion.py", line 1173, in _thread_return
return_data = func(*args, **kwargs)
File "/root/salt/salt/modules/state.py", line 1045, in show_top
top_ = st_.get_top()
File "/root/salt/salt/state.py", line 2436, in get_top
tops = self.get_tops()
File "/root/salt/salt/state.py", line 2313, in get_tops
saltenv=saltenv
File "/root/salt/salt/template.py", line 79, in compile_template
ret = render(input_data, saltenv, sls, **render_kwargs)
File "/root/salt/salt/renderers/yaml.py", line 50, in render
data = load(yaml_data, Loader=get_yaml_loader(argline))
File "/usr/lib/python2.7/dist-packages/yaml/__init__.py", line 71, in load
return loader.get_single_data()
File "/usr/lib/python2.7/dist-packages/yaml/constructor.py", line 37, in get_single_data
node = self.get_single_node()
File "/usr/lib/python2.7/dist-packages/yaml/composer.py", line 36, in get_single_node
document = self.compose_document()
File "/usr/lib/python2.7/dist-packages/yaml/composer.py", line 55, in compose_document
node = self.compose_node(None, None)
File "/usr/lib/python2.7/dist-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/usr/lib/python2.7/dist-packages/yaml/composer.py", line 127, in compose_mapping_node
while not self.check_event(MappingEndEvent):
File "/usr/lib/python2.7/dist-packages/yaml/parser.py", line 98, in check_event
self.current_event = self.state()
File "/usr/lib/python2.7/dist-packages/yaml/parser.py", line 439, in parse_block_mapping_key
"expected <block end>, but found %r" % token.id, token.start_mark)
ParserError: while parsing a block mapping
in "<unicode string>", line 1, column 1:
base:
^
expected <block end>, but found '<block sequence start>'
in "<unicode string>", line 3, column 5:
- state1
^

# Fixed code
def minion_config(opts, vm_):
    """
    Return a minion's configuration for the provided options and VM
    """

    # Don't start with a copy of the default minion opts; they're not always
    # what we need. Some default options are Null, let's set a reasonable default
    minion = {
        "master": "salt",
        "log_level": "info",
        "hash_type": "sha256",
    }

    # Now, let's update it to our needs
    minion["id"] = vm_["name"]
    master_finger = salt.config.get_cloud_config_value("master_finger", vm_, opts)
    if master_finger is not None:
        minion["master_finger"] = master_finger
    minion.update(
        # Get ANY defined minion settings, merging data, in the following order
        # 1. VM config
        # 2. Profile config
        # 3. Global configuration
        salt.config.get_cloud_config_value(
            "minion", vm_, opts, default={}, search_global=True
        )
    )

    make_master = salt.config.get_cloud_config_value("make_master", vm_, opts)
    if "master" not in minion and make_master is not True:
        raise SaltCloudConfigError(
            "A master setting was not defined in the minion's configuration."
        )

    # Get ANY defined grains settings, merging data, in the following order
    # 1. VM config
    # 2. Profile config
    # 3. Global configuration
    minion.setdefault("grains", {}).update(
        salt.config.get_cloud_config_value(
            "grains", vm_, opts, default={}, search_global=True
        )
    )
    return minion