Locks
Terrateam ensures that changes are safely applied using Locks.
What is a Lock?
A lock is a guarantee that only a single change to a resource can be applied in a pull request at any given time. A change to a matching resource in another pull request cannot be concurrently applied.
When is a Lock Acquired?
When executing an Apply operation, a lock is acquired on the Dirspaces that are targeted in the pull request.
When is a Lock Not Acquired?
The explanations below assume the default locking policy strict
is enabled.
If a pull request is created but never applied or merged, then no lock is acquired.
A lock is only acquired when executing an Apply or merging a pull request without executing an Apply.
Example 1: Applying
Consider a pull request that has a change in dir1
and dir2
.
Only the default
workspace will be used in this example.
Alice performs the following operations:
terrateam plan
- Alice plans all changes in the pull request.terrateam apply dir:dir1
- Alice applies only the changes indir1
.
The pull request now owns locks on the following Dirspaces:
(dir1, default)
(dir2, default)
Example 2: Merging
Consider the example pull request from Example 1.
Instead of executing a terrateam apply
, Alice merges the pull request with unapplied changes.
The pull request now owns locks on the following Dirspaces:
(dir1, default)
(dir2, default)
When is a Lock Released?
A lock is released when a change has been both applied and merged.
Unlocking
In certain scenarios, the user may want to force an unlock.
To explicitly remove a lock, comment terrateam unlock
in the pull request
that owns the lock.
- Executing a
terrateam unlock
only applies to those locks that were acquired prior to performing the unlock. - Performing a merge or
apply
after anunlock
will acquire any necessary locks again.
If Alice performs the following operations:
terrateam plan
terrateam apply
terrateam unlock
terrateam plan
terrateam apply
On step (5) all locks that were acquired in step (2) will be acquired again.
Benefits of Locks
Drift Protection
Locks are released when a change is both merged and applied to ensure that your default branch matches the real-world state of your infrastructure.
Consider a pull request where a change is applied but Alice accidentally closes the pull request instead of merging it. Without the pull request merged, future pull requests would not be created on top of Alice’s change.
With locks, future changes to the same Dirspace could not be applied because Alice’s pull request still owns the lock. Alice’s change would need to be explicitly unlocked or the pull request would have to be re-opened and merged.
Multiple Pull Requests and Identical Resources
Another scenario is two pull requests modifying the same Terraform resource. This can cause the state defined in your configuration to be different from the real-world state of your infrastructure.
Consider two open pull requests without the ability to lock:
PR1
created by AlicePR2
created by Bob
Timeline:
- Alice and Bob both makes changes to
dir1
- Alice applies her changes in
PR1
but does not merge - Bob applies his change in
PR2
, changing the same resources that Alice applied against - Bob merges his pull request before Alice merges her pull request
Examining the repository, one could assume that the latest changes in the default branch
match the real-world state of the infrastructure.
In this scenario, those would be Alice’s changes. In reality, the real-world state does not match her changes but match Bob’s changes.
With locks, we can guarantee that the changes are merged in the order they are applied.
Merging without Applying
Terrateam will not prevent a user from merging a pull request without issuing a terrateam apply
. You are in control of your Terraform repository and real-world state of your infrastructure.
However, Terrateam will recognize this scenario. Users will not be able to apply any new changes until locks have been released from the merged pull request that was not applied.
Example
Consider the following scenario:
- A repository named
repo
- Alice creates pull request
PR1
againstrepo
- Bob creates pull request
PR2
againstrepo
- Both pull requests have a change in directory
dir
Only the default
workspace will be used in this example.
Timeline:
- Alice applies her change by commenting
terrateam apply
but does not merge the pull request- The
PR1
pull request now owns a lock on the Dirspace(dir, default)
- The
- Bob tries to execute a
terrateam apply
onPR2
, but receives an error stating that the plan cannot be applied becausePR1
owns the lock - Alice merges
PR1
. The lock is released and aterrateam apply
can be executed againstPR2
. - Bob tries to execute a
terrateam apply
onPR2
again but receives an error stating that the plan has been invalidated
The terrateam apply
Alice executed in PR1
changed the state marking Bob’s plan as invalid.
Bob now needs to run terrateam plan
again before running terrateam apply
.
Locking Policies
The lock_policy
option instructs Terrateam under what situations it should acquire a lock. See Workflows for configuration details.
strict
This is the default mode and matches the current behavior described above. If a user comments terrateam apply
in the pull request or the change is merged, Terrateam acquires a lock on the directory until the complimentary operation is performed. We recommend this locking policy for production environments.
apply
This instructs Terrateam to only acquire a lock if the directory has been applied in Terrateam (terrateam apply
). The lock will be released once the change is merged. If the change is just merged, Terrateam will not acquire a lock.
merge
This instructs Terrateam to only acquire a lock if the directory has been merged. The lock will be released when the change is applied (terrateam apply
). This is useful if a pull request is used as a playground in development and then closed when done, rather than merging.
none
Never acquire a lock.