Skip to content

Commit

Permalink
add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
norman-zon committed Dec 12, 2024
1 parent 54cf362 commit 3d2711d
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 0 deletions.
19 changes: 19 additions & 0 deletions test/fixtures/tofu-state-encryption/aws-kms/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Test AWS KMS encryption with local state
remote_state {
backend = "local"

generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}

config = {
path = "${get_terragrunt_dir()}/${path_relative_to_include()}/terraform.tfstate"
}

encryption = {
key_provider = "aws_kms"
kms_key_id = "__FILL_IN_KMS_KEY_ID__"
key_spec = "AES_256"
}
}
19 changes: 19 additions & 0 deletions test/fixtures/tofu-state-encryption/gcp-kms/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Test GCP KMS encryption with local state
remote_state {
backend = "local"

generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}

config = {
path = "${get_terragrunt_dir()}/${path_relative_to_include()}/terraform.tfstate"
}

encryption = {
key_provider = "gcp_kms"
kms_encryption_key = "__FILL_IN_KMS_KEY_ID__"
key_length = 1024
}
}
18 changes: 18 additions & 0 deletions test/fixtures/tofu-state-encryption/pbkdf2/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Test PBKDF2 encryption with local state
remote_state {
backend = "local"

generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}

config = {
path = "${get_terragrunt_dir()}/${path_relative_to_include()}/terraform.tfstate"
}

encryption = {
key_provider = "pbkdf2"
passphrase = "randompassphrase123456"
}
}
100 changes: 100 additions & 0 deletions test/integration_tofu_state_encryption_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// TODO add build flag //go:build tofu

package test_test

import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"testing"

"github.com/gruntwork-io/terragrunt/test/helpers"
"github.com/gruntwork-io/terragrunt/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const (
testFixtureTofuStateEncryptionPBKDF2 = "fixtures/tofu-state-encryption/pbkdf2"
testFixtureTofuStateEncryptionGCPKMS = "fixtures/tofu-state-encryption/gcp-kms"
testFixtureTofuStateEncryptionAWSKMS = "fixtures/tofu-state-encryption/aws-kms"
gcpKMSKeyID = "projects/terragrunt-test/locations/global/keyRings/terragrunt-test/cryptoKeys/terragrunt-test-key"
awsKMSKeyID = "arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012"
stateFile = "terraform.tfstate"
awsKMSKeyRegion = "us-west-2"
)

func TestTofuStateEncryptionPBKDF2(t *testing.T) {
t.Parallel()

tmpEnvPath := helpers.CopyEnvironment(t, testFixtureTofuStateEncryptionPBKDF2)
workDir := util.JoinPath(tmpEnvPath, testFixtureTofuStateEncryptionPBKDF2)

helpers.RunTerragrunt(t, fmt.Sprintf("terragrunt apply -auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s", workDir))
assert.True(t, helpers.FileIsInFolder(t, stateFile, workDir))
validateStateIsEncrypted(t, stateFile, workDir)
}

func TestTofuStateEncryptionGCPKMS(t *testing.T) {
t.Parallel()

tmpEnvPath := helpers.CopyEnvironment(t, testFixtureTofuStateEncryptionGCPKMS)
workDir := util.JoinPath(tmpEnvPath, testFixtureTofuStateEncryptionGCPKMS)
configPath := util.JoinPath(workDir, "terragrunt.hcl")

helpers.CopyAndFillMapPlaceholders(t, configPath, configPath, map[string]string{
"__FILL_IN_KMS_KEY_ID__": gcpKMSKeyID,
})

helpers.RunTerragrunt(t, fmt.Sprintf("terragrunt apply -auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s", workDir))
assert.True(t, helpers.FileIsInFolder(t, stateFile, workDir))
validateStateIsEncrypted(t, stateFile, workDir)
}

func TestTofuStateEncryptionAWSKMS(t *testing.T) {
t.Parallel()

tmpEnvPath := helpers.CopyEnvironment(t, testFixtureTofuStateEncryptionAWSKMS)
workDir := util.JoinPath(tmpEnvPath, testFixtureTofuStateEncryptionAWSKMS)
configPath := util.JoinPath(workDir, "terragrunt.hcl")

helpers.CopyAndFillMapPlaceholders(t, configPath, configPath, map[string]string{
"__FILL_IN_KMS_KEY_ID__": awsKMSKeyID,
})

os.Setenv("AWS_REGION", awsKMSKeyRegion)
helpers.RunTerragrunt(t, fmt.Sprintf("terragrunt apply -auto-approve --terragrunt-non-interactive --terragrunt-working-dir %s", workDir))
assert.True(t, helpers.FileIsInFolder(t, stateFile, workDir))
validateStateIsEncrypted(t, stateFile, workDir)
}

// Check the statefile contains an encrypted_data key
// and that the encrypted_data is base64 encoded
func validateStateIsEncrypted(t *testing.T, fileName string, path string) {
t.Helper()

filePath := filepath.Join(path, fileName)
file, err := os.Open(filePath)
require.NoError(t, err)
defer file.Close()

byteValue, err := io.ReadAll(file)
require.NoError(t, err)

var result map[string]interface{}
err = json.Unmarshal(byteValue, &result)
assert.NoError(t, err, "Error unmarshalling the state file '%s'", fileName)

encryptedData, exists := result["encrypted_data"]
assert.True(t, exists, "The key 'encrypted_data' should exist in the state '%s'", fileName)

// Check if the encrypted_data is base64 encoded (common for AES-256 encrypted data)
encryptedDataStr, ok := encryptedData.(string)
assert.True(t, ok, "The value of 'encrypted_data' should be a string")

_, err = base64.StdEncoding.DecodeString(encryptedDataStr)
assert.NoError(t, err, "The value of 'encrypted_data' should be base64 encoded, indicating AES-256 encryption")
}

0 comments on commit 3d2711d

Please sign in to comment.