The two terms are very different.
Let us start with immutability
, which literally means "no mutations" or "no changes". In the DevOps sense, it means that once you created an artifact, be that a container image, or a VM image, or maybe a package from compiled code - you declare that you will never ever change it. Often if any changes are required, you declare that a new version of "thing" will be created instead.
The term idempotence
means that when changes are applied multiple times, the state is mutated (changed) just once. First, it already assumes that there are going to be changes applied which means that you cannot have something both immutable and have idempotent actions done to it (no actions are done to it by contract).
In the use of configuration management tools, idempotence
is used in some cases when applying the same change multiple times. Like adding the line that says localhost
to the /etc/hosts
file, you don't really need multiple such lines and if one already exists it is safe to not try to append again.
Also idempotent
is a term used to describe actions that attempt to change things, while immutable
is used to describe nouns (objects) that are set against changes done to them.
Why is an immutable
object useful? Because when you copy it around, for example from a dev environment to qa to production. You already know quite a lot (but not everything) regarding how it is going to behave. In many cases, the parts that are working will be consistent, and the parts that are broken are going to be consistent as well.
Why are idempotent
actions useful? Because when you want to change a state of some object, in many cases it is useful to only verify that the change has been applied and apply changes just in case it is required. For example, when a configuration item in a file is missing or has the wrong value, it is useful to add it just once or change it just once while applying the action multiple times. In many other cases, like log files, you don't want to have idempotent actions because you often do want to append another line each time some event happens.