Regarding the AlphaZero vs Stockfish match, this question has already been covered here by SmallChess.
AlphaZero aside (which employs a specialised Monte Carlo1 routine in its exploration of the lines of play), which is made to be non-deterministic by construction, for the usual heuristics based chess engines, such as Stockfish and others (though there are other engines that have MC-based routines, AFAIK Rybka used to have such feature), the source of randomness is generally just a consequence of technical aspects in the implementation, rather than intentional randomness being introduced algorithmically in the engine's decision making. Abstractly speaking, one reason for that is the fact that the engines aren't running in a purely sequential manner (executing one task after the other). Instead, to render the engines more efficient, they perform parallel searches in various branches of the tree of possible moves. They do so via what is called multi-threading (or -processing but that is a bit different). So multiple threads of the CPUs are concurrently executing operations to search the tree (and cache the evaluations of visited positions), so imagine each thread being assigned a subtree. The problem with this kind of implementation is that the overall execution of the threads becomes highly dependent on all sorts of conditions (waiting times, RAM swaps, ...), so in the end a principal variation may be chosen without having allowed all other threads to finish their search.
This indeed happens often because the engine is set to make a decision under a certain amount of time, so time management alters the behaviour. You can also revert this statement by saying: knowing the algorithm and implementing deterministic threading routines are not sufficient to reliably predict the state of the program after any time t. Of course if one always allows all threads to finish their search, and there haven't been concurrency issues during that execution (for instance a thread trying to access a certain cache that isn't accessible), then the behaviour will indeed be fully reproducible given everything else is the same2.
1: Together with the fact that through additional training (for instance self-play) its neural network keeps evolving (re-adjusted parameters), or if you will its evaluation function doesn't have a constant, fixed definition (unlike heuristics based engines).
2: Even then, as you said, at the opening level, with an opening book, there are sometimes intentional random decisions made by the engine as to which variation to choose. Similarly, outside of the opening phase, there can be moments where multiple variations have close to equal evaluations (within the resolution chosen for the Eval), then based on the design, it may end up choosing one randomly. Finally, at the level of engine settings you have to be careful as well, for instance the depth of search and ponder times chosen for each engine (and whether they can further calculate during each other's ponder times).