Skip reading encryption keys on tofu init with -backend=false flag set (#2293)

Signed-off-by: Sekiranda <sekirandahamza@gmail.com>
This commit is contained in:
Sekiranda Hamza 2024-12-20 11:45:12 +03:00 committed by GitHub
parent 27ab52fd03
commit 211ec55a30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 6 deletions

View File

@ -7,6 +7,7 @@ NEW FEATURES:
ENHANCEMENTS:
BUG FIXES:
* `tofu init` command does not attempt to read encryption keys when `-backend=false` flag is set. (https://github.com/opentofu/opentofu/pull/2293)
## Previous Releases

View File

@ -204,12 +204,19 @@ func (c *InitCommand) Run(args []string) int {
return 1
}
// Load the encryption configuration
enc, encDiags := c.EncryptionFromModule(rootModEarly)
diags = diags.Append(encDiags)
if encDiags.HasErrors() {
c.showDiagnostics(diags)
return 1
var enc encryption.Encryption
// If backend flag is explicitly set to false i.e -backend=false, we disable state and plan encryption
if backendFlagSet && !flagBackend {
enc = encryption.Disabled()
} else {
// Load the encryption configuration
var encDiags tfdiags.Diagnostics
enc, encDiags = c.EncryptionFromModule(rootModEarly)
diags = diags.Append(encDiags)
if encDiags.HasErrors() {
c.showDiagnostics(diags)
return 1
}
}
var back backend.Backend

View File

@ -3065,6 +3065,75 @@ func TestInit_invalidExtraLabel(t *testing.T) {
}
}
func TestInit_skipEncryptionBackendFalse(t *testing.T) {
t.Run("init success with encryption present and -backend=false", func(t *testing.T) {
// Create a temporary working directory that is empty
td := t.TempDir()
testCopyDir(t, testFixturePath("init-encryption-available"), td)
defer testChdir(t, td)()
overrides := metaOverridesForProvider(testProvider())
ui := new(cli.MockUi)
view, _ := testView(t)
providerSource, closeCallback := newMockProviderSource(t, map[string][]string{
// mock aws provider
"hashicorp/aws": {"5.0", "5.8"},
})
defer closeCallback()
m := Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
ProviderSource: providerSource,
}
c := &InitCommand{
Meta: m,
}
args := []string{
"-backend=false", // should disable reading encryption key run init successfully
}
if code := c.Run(args); code != 0 {
t.Fatalf("init should run successfully with -backend=false: \ngot error : %s\n", ui.ErrorWriter.String())
}
})
t.Run("init fails with encryption present -backend=false not set", func(t *testing.T) {
// Create a temporary working directory that is empty
td := t.TempDir()
testCopyDir(t, testFixturePath("init-encryption-available"), td)
defer testChdir(t, td)()
overrides := metaOverridesForProvider(testProvider())
ui := new(cli.MockUi)
view, _ := testView(t)
providerSource, closeCallback := newMockProviderSource(t, map[string][]string{
// mock aws provider
"hashicorp/aws": {"5.0", "5.8"},
})
defer closeCallback()
m := Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
ProviderSource: providerSource,
}
c := &InitCommand{
Meta: m,
}
var args []string
// Check error is generated from trying to read encryption key or fail test
if code := c.Run(args); code == 0 {
t.Fatalf("init should not run successfully\n")
} else if !strings.Contains(ui.ErrorWriter.String(), "key_provider.aws_kms.key failed with error:") {
t.Fatalf("generated error should contain the string \"Error: Unable to fetch encryption key data\"\ninstead got : %s\n", ui.ErrorWriter.String())
}
})
}
// newMockProviderSource is a helper to succinctly construct a mock provider
// source that contains a set of packages matching the given provider versions
// that are available for installation (from temporary local files).

View File

@ -0,0 +1,33 @@
variable "encryption_kms_key_id" {
type = string
default = "1234abcd-12ab-34cd-56ef-1234567890ab"
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.8"
}
}
encryption {
key_provider "aws_kms" "key" {
kms_key_id = var.encryption_kms_key_id
region = "eu-central-1"
key_spec = "AES_256"
}
method "aes_gcm" "encrypt-aes" {
keys = key_provider.aws_kms.key
}
state {
enforced = true
method = method.aes_gcm.encrypt-aes
}
plan {
enforced = true
method = method.aes_gcm.encrypt-aes
}
}
}