Learn › Linux Automation with Salt › Ask the right machines

Ask the right machines

Choose exact IDs or a list, request facts from real agents, and distinguish a missing return from a reported result.

Ask the right machines

An automation command has two questions hidden inside it: which machines should receive this request, and what should happen there? A correct operation sent to the wrong machine is still a mistake.

In this lesson, you will request facts from the two agents you enrolled in Lesson 1. You will choose recipients before running a command, compare the replies with that choice, and explain an incomplete result without guessing its cause. No package, file or service change is needed for a healthy fleet.

Before you begin: finish Meet and trust your fleet. You should be able to identify the master terminal, explain why each minion key was accepted, and obtain a fresh Salt reply from each named agent. Basic shell quoting and sudo are enough; no programming is required.

Keep the same running three-machine session if it is still available. A fresh session starts with the Lesson 1 configuration: both minions need verified enrollment, and the second has a wrong master address to diagnose. Complete that preparation before these exercises. A previous session's keys and fingerprints do not identify newly created machines.

Separate the recipient from the request

Run Salt requests in the salt-master terminal. Here is the request you already know:

sudo salt 'minion-a' test.ping

The master publishes the request; matching, connected agents execute it and send back their own results. The target describes who should act. It is not an IP route, a service-health test or an independent check of identity.

{"caption":"One logical request and its named result. This is not a network-packet diagram; the minion establishes the Salt connections to its master.","direction":"vertical","nodes":[{"id":"request","label":"Master request"},{"id":"agent","label":"minion-a"},{"id":"return","label":"Named result"}],"edges":[{"from":"request","to":"agent","label":"matches ID","kind":"plain","stage":1},{"from":"agent","to":"return","label":"test.ping","kind":"plain","stage":2}]}

Salt normally labels each returned result with a minion ID. Read that label as well as the value. A True underneath minion-a is evidence that this agent answered this request; it does not establish that every service on that machine is healthy.

Choose the scope before running

Our intended fleet contains the verified IDs minion-a and minion-b. These three selectors mean different things:

A glob is a pattern: * can match any sequence of characters. Quote the pattern so your shell passes it to Salt rather than trying to match local filenames first. A naming pattern can be convenient, but it is not a permanent membership boundary: adding minion-c could widen its scope.

Do not omit -L from a list request: 'minion-a,minion-b' by itself is one glob expression containing a comma, not a two-ID list.

Inspect the trusted inventory and one reply

In the master terminal:

sudo salt-key --list=accepted
sudo salt --timeout=8 'minion-a' test.ping

Find both previously verified IDs in the accepted-key list. Do not accept an unfamiliar key just to make a request succeed. The list records accepted identities; it does not tell you which agents are currently connected.

For the second command, look for a result labeled minion-a with the value True. Record the ID and value you actually see. We use an eight-second wait for this small practice fleet; it is a collection window, not a promise about network speed or application readiness.

If the expected reply is absent, stop this worked path and use the investigation step later in this lesson. Do not invent a successful result. You can inspect an agent through its management terminal even when it cannot answer Salt.

Ask for only the facts you need

Suppose you need the reported operating system for minion-a, before choosing a compatible package later. On the master:

sudo salt --timeout=8 'minion-a' grains.item id os

Grains are facts made available by a minion. grains.item requests named entries; here, id and os. Inspect the outer minion-ID label, then the values inside its result. In this prepared Debian fleet, the normal OS report is Debian. Use your actual response as evidence; a different value deserves investigation.

The outer result label identifies which minion returned this entry. The id grain is also reported by the agent. Neither a familiar label nor a reported OS independently repeats Lesson 1's fingerprint verification. A compromised or misconfigured agent may report misleading facts.

Account for both machines

Before this request, write the expected return IDs: minion-a and minion-b. Then run it on the master:

sudo salt --timeout=8 -L 'minion-a,minion-b' grains.item id os

Read the whole result. The order of replies can vary. Compare a set of IDs, not which reply appeared first.

Make a separate entry in your notes for minion-a and minion-b. For each one, record whether a result arrived, its id and os values or the actual error, and what remains unknown. In both cases, application health is still untested.

A successful reply from one agent does not stand in for another. Distinguish three observations: a reply with the requested facts, a reply reporting an error, and no result collected for an expected ID. These lead to different next checks.

If both intended agents report the expected facts, leave their configuration alone. A useful operational decision can be: the evidence answers this question; no machine change is justified.

Correct the target and verify it

An operator wants facts from both agents and proposes:

sudo salt --timeout=8 'minion-a,minion-b' grains.item id os

Explain the mismatch before running anything: without -L, Salt receives a single glob expression. Replace the target syntax with the explicit list form from the previous step, then verify that both intended IDs returned facts.

Now compare with a quoted pattern, using only this read-only query:

sudo salt --timeout=8 'minion-*' grains.item id os

In our two-agent inventory, it should select the same IDs. Record whether it did. That does not make the two selectors interchangeable in a growing fleet.

The justified change here was to the proposed request, not to a healthy server. Verification means comparing the returned IDs with the intended set, then interpreting each result.

Investigate silence without guessing

On the master, predict the result of asking a name that is not in this lab inventory, then try this read-only request:

sudo salt --timeout=8 'minion-does-not-exist' test.ping

Expect no successful named minion reply; the CLI may report that no minions matched. Read its actual message. Do not reinterpret that message as a Boolean False returned by an agent.

Silence from a real expected ID needs more investigation. A wrong target, an unavailable agent, a trust problem, a broken path or a late response can all prevent collection of the expected result. A timeout means the CLI stopped waiting; it does not prove that a requested operation never ran. This matters especially before retrying a later operation that changes something.

For a genuinely missing minion-b reply, first compare the target with the accepted-key list on the master. Through the minion-b management terminal, inspect:

sudo systemctl is-active salt-minion
sudo journalctl -u salt-minion -n 20 --no-pager
ip route get 10.77.0.10

A service status, a recent log message and a route selection each answer a different question. Explain what you would check next and why. Use Lesson 1's configuration and trust procedure if its prerequisites are not satisfied. Do not reset keys, edit routes or restart healthy services just because the first query was incomplete. After a justified repair, rerun a narrow request and account for both agents again.

Your turn: change the request

Close the earlier command examples. A teammate needs the reported operating system from minion-b only. Minion-a must be excluded.

Write your intended ID set and choose a read-only command. Run it in the correct terminal, then explain:

1. Why your target includes minion-b and excludes minion-a. 2. Which ID returned, what its OS fact says, and whether an error or missing reply changed your conclusion. 3. What the result does not prove about trust or application health. 4. Whether any machine change is justified by this request.

If you needed to reopen the example, record that help and try the task again later without it. A command that ran successfully is useful evidence; it is not an assessment of your explanation.

Keep an evidence note and return later

Keep a short note: question → intended IDs → command → observed IDs and results → missing evidence → decision → verification. Do not paste secrets or private keys into it.

This lesson has no automatic pass score. The Lesson 1 enrollment check does not measure target selection or your reasoning. Reading progress records that you opened steps; it does not certify independent mastery.

On your next visit, before looking back at the worked example, reason about this changed accepted inventory: minion-a, minion-b, and minion-backup. The requirement still names only minion-a and minion-b. Choose a target, predict which IDs it selects and which replies you would expect if both agents are available, and explain why 'minion-*' would widen the intended scope. Selection does not guarantee a reply. This is a reasoning exercise; the current lab still has two minions.

When the next lesson is available, reuse that target decision before the first managed-file change. You will describe a required result, inspect what changed, and repeat the request to check whether further work was needed.

References: Salt 3006 target matching, Salt CLI, missing returns and timeouts. This lesson's command behavior is reviewed against the lab's pinned Salt 3006.27 implementation.

Practice Ask the right machines in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.