Repository navigation
Expand file tree
/
Copy pathencryption.tofu
More file actions
73 lines (61 loc) · 2.28 KB
/
Copy pathencryption.tofu
File metadata and controls
73 lines (61 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# encryption.tofu
terraform {
encryption {
# pbkdf2 stores its salt in the state's meta section under a key. Without
# an alias that key is the provider's own address, which welds the block
# name to every byte it ever encrypted; the stable alias below is what
# makes passphrase rotation a pure secrets-file operation.
key_provider "pbkdf2" "main" {
passphrase = var.state_passphrase
encrypted_metadata_alias = "state"
}
# Standing rotation slot. Writes always use main; previous is only ever
# tried when decrypting something main cannot. Outside a rotation window
# it holds a placeholder and is never consulted. Rotation procedure:
# README.md, "Rotating the state passphrase".
key_provider "pbkdf2" "previous" {
passphrase = var.state_passphrase_previous
encrypted_metadata_alias = "state"
}
method "aes_gcm" "main" {
keys = key_provider.pbkdf2.main
}
method "aes_gcm" "previous" {
keys = key_provider.pbkdf2.previous
}
# enforced: refuse to ever read or write plaintext state/plans, rather than
# falling back silently if this block stops resolving.
state {
method = method.aes_gcm.main
enforced = true
fallback {
method = method.aes_gcm.previous
}
}
plan {
method = method.aes_gcm.main
enforced = true
fallback {
method = method.aes_gcm.previous
}
}
}
}
variable "state_passphrase" {
type = string
sensitive = true
validation {
condition = length(var.state_passphrase) >= 16
error_message = "state_passphrase must be at least 16 characters (the pbkdf2 minimum). An empty value usually means tofu.env was not sourced or sops failed to decrypt."
}
}
variable "state_passphrase_previous" {
description = "Pre-rotation passphrase, tried only when the current one cannot decrypt. Holds a placeholder outside rotation windows; sourced from secrets.enc.json state.passphrase_previous by tofu.env."
type = string
sensitive = true
default = "rotation-placeholder-unused"
validation {
condition = length(var.state_passphrase_previous) >= 16
error_message = "state_passphrase_previous must be at least 16 characters (the pbkdf2 minimum)."
}
}