Skip to content

Commit

Permalink
Conditionally set log level of s3 bucket encryption warning (#2878)
Browse files Browse the repository at this point in the history
* Conditionally set log level of s3 bucket encryption warning

* rename options to opts
  • Loading branch information
kaden-l-nelson committed Apr 4, 2024
1 parent e917b53 commit 0b81421
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/_docs/04_reference/config-blocks-and-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ For the `s3` backend, the following additional properties are supported in the `
- `region` - (Optional) The region of the S3 bucket.
- `profile` - (Optional) This is the AWS profile name as set in the shared credentials file.
- `endpoint` - (Optional) A custom endpoint for the S3 API.
- `encrypt` - (Optional) Whether to enable server side encryption of the state file.
- `encrypt` - (Optional) Whether to enable server side encryption of the state file. If disabled, a log warning will be issued in the console output to notify the user. If `skip_bucket_ssencryption` is enabled, the log will be written as a debug log.
- `role_arn` - (Optional) The role to be assumed.
- `shared_credentials_file` - (Optional) This is the path to the shared credentials file. If this is not set and a profile is specified, `~/.aws/credentials` will be used.
- `external_id` - (Optional) The external ID to use when assuming the role.
Expand Down
7 changes: 6 additions & 1 deletion remote/remote_state_s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,12 @@ func validateS3Config(extendedConfig *ExtendedRemoteStateConfigS3, terragruntOpt
}

if !config.Encrypt {
terragruntOptions.Logger.Warnf("Encryption is not enabled on the S3 remote state bucket %s. Terraform state files may contain secrets, so we STRONGLY recommend enabling encryption!", config.Bucket)
msg := fmt.Sprintf("Encryption is not enabled on the S3 remote state bucket %s. Terraform state files may contain secrets, so we STRONGLY recommend enabling encryption!", config.Bucket)
if extendedConfig.SkipBucketSSEncryption {
terragruntOptions.Logger.Debug(msg)
} else {
terragruntOptions.Logger.Warn(msg)
}
}

return nil
Expand Down
76 changes: 76 additions & 0 deletions remote/remote_state_s3_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package remote

import (
"bytes"
"testing"

"github.com/aws/aws-sdk-go/service/s3"
"github.com/sirupsen/logrus"

"github.com/aws/aws-sdk-go/aws"
"github.com/gruntwork-io/terragrunt/aws_helper"
Expand Down Expand Up @@ -453,3 +455,77 @@ func TestNegativePublicAccessResponse(t *testing.T) {
})
}
}

func TestValidateS3Config(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
extendedConfig *ExtendedRemoteStateConfigS3
expectedErr error
expectedOutput string
}{
{
name: "no-region",
extendedConfig: &ExtendedRemoteStateConfigS3{},
expectedErr: MissingRequiredS3RemoteStateConfig("region"),
},
{
name: "no-bucket",
extendedConfig: &ExtendedRemoteStateConfigS3{
remoteStateConfigS3: RemoteStateConfigS3{
Region: "us-west-2",
},
},
expectedErr: MissingRequiredS3RemoteStateConfig("bucket"),
},
{
name: "no-key",
extendedConfig: &ExtendedRemoteStateConfigS3{
remoteStateConfigS3: RemoteStateConfigS3{
Region: "us-west-2",
Bucket: "state-bucket",
},
},
expectedErr: MissingRequiredS3RemoteStateConfig("key"),
},
{
name: "log-warning-skip-bucket-sse-encryption",
extendedConfig: &ExtendedRemoteStateConfigS3{
remoteStateConfigS3: RemoteStateConfigS3{
Region: "us-west-2",
Bucket: "state-bucket",
Key: "terraform.tfstate",
},
},
expectedOutput: "level=warning msg=\"Encryption is not enabled",
},
{
name: "log-debug-skip-bucket-sse-encryption",
extendedConfig: &ExtendedRemoteStateConfigS3{
SkipBucketSSEncryption: true,
remoteStateConfigS3: RemoteStateConfigS3{
Region: "us-west-2",
Bucket: "state-bucket",
Key: "terraform.tfstate",
},
},
expectedOutput: "level=debug msg=\"Encryption is not enabled",
},
}
for _, testCase := range testCases {
testCase := testCase

t.Run(testCase.name, func(t *testing.T) {
buf := &bytes.Buffer{}
logger := logrus.New()
logger.SetLevel(logrus.DebugLevel)
logger.SetOutput(buf)
opts := &options.TerragruntOptions{Logger: logrus.NewEntry(logger)}
err := validateS3Config(testCase.extendedConfig, opts)
if err != nil {
assert.ErrorIs(t, err, testCase.expectedErr)
}
assert.Contains(t, buf.String(), testCase.expectedOutput)
})
}
}

0 comments on commit 0b81421

Please sign in to comment.