Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package terragrunt for openSUSE:Factory checked in at 2022-11-30 15:00:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/terragrunt (Old) and /work/SRC/openSUSE:Factory/.terragrunt.new.1597 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "terragrunt" Wed Nov 30 15:00:02 2022 rev:19 rq:1038914 version:0.42.0 Changes: -------- --- /work/SRC/openSUSE:Factory/terragrunt/terragrunt.changes 2022-11-25 13:22:57.963618632 +0100 +++ /work/SRC/openSUSE:Factory/.terragrunt.new.1597/terragrunt.changes 2022-11-30 15:01:01.201724410 +0100 @@ -1,0 +2,6 @@ +Tue Nov 29 14:07:41 UTC 2022 - ka...@b1-systems.de + +- Update to version 0.42.0: + * #1717 Enable security layers for access logging buckets (#2367) + +------------------------------------------------------------------- Old: ---- terragrunt-0.41.0.tar.gz New: ---- terragrunt-0.42.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ terragrunt.spec ++++++ --- /var/tmp/diff_new_pack.i5hRQU/_old 2022-11-30 15:01:01.905728284 +0100 +++ /var/tmp/diff_new_pack.i5hRQU/_new 2022-11-30 15:01:01.909728306 +0100 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: terragrunt -Version: 0.41.0 +Version: 0.42.0 Release: 0 Summary: Thin wrapper for Terraform for working with multiple Terraform modules License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.i5hRQU/_old 2022-11-30 15:01:01.953728549 +0100 +++ /var/tmp/diff_new_pack.i5hRQU/_new 2022-11-30 15:01:01.957728570 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/gruntwork-io/terragrunt</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.41.0</param> + <param name="revision">v0.42.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> @@ -16,7 +16,7 @@ <param name="compression">gz</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">terragrunt-0.41.0.tar.gz</param> + <param name="archive">terragrunt-0.42.0.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.i5hRQU/_old 2022-11-30 15:01:01.981728702 +0100 +++ /var/tmp/diff_new_pack.i5hRQU/_new 2022-11-30 15:01:01.985728725 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/gruntwork-io/terragrunt</param> - <param name="changesrevision">a83a7b8a0f4cb147f9637ecf9200be83c8ea3883</param></service></servicedata> + <param name="changesrevision">d9eca946aa272ff0d99a34d26138abdea32ab2ff</param></service></servicedata> (No newline at EOF) ++++++ terragrunt-0.41.0.tar.gz -> terragrunt-0.42.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/docs/_docs/04_reference/config-blocks-and-attributes.md new/terragrunt-0.42.0/docs/_docs/04_reference/config-blocks-and-attributes.md --- old/terragrunt-0.41.0/docs/_docs/04_reference/config-blocks-and-attributes.md 2022-11-24 18:43:36.000000000 +0100 +++ new/terragrunt-0.42.0/docs/_docs/04_reference/config-blocks-and-attributes.md 2022-11-29 13:32:50.000000000 +0100 @@ -395,7 +395,7 @@ - `disable_aws_client_checksums`: When `true`, disable computing and checking checksums on the request and response, such as the CRC32 check for DynamoDB. This can be used to workaround https://github.com/gruntwork-io/terragrunt/issues/1059. -- `accesslogging_bucket_name`: (Optional) When provided as a valid `string`, create an S3 bucket with this name to store the access logs for the S3 bucket used to store Terraform state. If not provided, or string is empty or invalid S3 bucket name, then server access logging for the S3 bucket storing the terraform state will be disabled. +- `accesslogging_bucket_name`: (Optional) When provided as a valid `string`, create an S3 bucket with this name to store the access logs for the S3 bucket used to store Terraform state. If not provided, or string is empty or invalid S3 bucket name, then server access logging for the S3 bucket storing the terraform state will be disabled. **Note:** When access logging is enabled supported encryption for state bucket is only `AES256`. Reference: [S3 server access logging](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html) - `accesslogging_target_prefix`: (Optional) When provided as a valid `string`, set the `TargetPrefix` for the access log objects in the S3 bucket used to store Terraform state. If set to **empty**`string`, then `TargetPrefix` will be set to **empty** `string`. If attribute is not provided at all, then `TargetPrefix` will be set to **default** value `TFStateLogs/`. This attribute won't take effect if the `accesslogging_bucket_name` attribute is not present. - `bucket_sse_algorithm`: (Optional) The algorithm to use for server side encryption of the state bucket. Defaults to `aws:kms`. - `bucket_sse_kms_key_id`: (Optional) The KMS Key to use when the encryption algorithm is `aws:kms`. Defaults to the AWS Managed `aws/s3` key. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/remote/remote_state_s3.go new/terragrunt-0.42.0/remote/remote_state_s3.go --- old/terragrunt-0.41.0/remote/remote_state_s3.go 2022-11-24 18:43:36.000000000 +0100 +++ new/terragrunt-0.42.0/remote/remote_state_s3.go 2022-11-29 13:32:50.000000000 +0100 @@ -363,6 +363,12 @@ 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) } + if extendedConfig.AccessLoggingBucketName != "" && extendedConfig.BucketSSEAlgorithm != s3.ServerSideEncryptionAes256 { + return errors.WithStackTrace(InvalidAccessLoggingBucketEncryption{ + BucketSSEAlgorithm: extendedConfig.BucketSSEAlgorithm, + }) + } + return nil } @@ -432,7 +438,7 @@ if bucketUpdatesRequired.SSEEncryption { if config.SkipBucketSSEncryption { terragruntOptions.Logger.Debugf("Server-Side Encryption is disabled for the remote state AWS S3 bucket %s using 'skip_bucket_ssencryption' config.", config.remoteStateConfigS3.Bucket) - } else if err := EnableSSEForS3BucketWide(s3Client, config, terragruntOptions); err != nil { + } else if err := EnableSSEForS3BucketWide(s3Client, config.remoteStateConfigS3.Bucket, config, terragruntOptions); err != nil { return err } } @@ -448,7 +454,7 @@ if bucketUpdatesRequired.EnforcedTLS { if config.SkipBucketEnforcedTLS { terragruntOptions.Logger.Debugf("Enforced TLS is disabled for the remote state AWS S3 bucket %s using 'skip_bucket_enforced_tls' config.", config.remoteStateConfigS3.Bucket) - } else if err := EnableEnforcedTLSAccesstoS3Bucket(s3Client, config, terragruntOptions); err != nil { + } else if err := EnableEnforcedTLSAccesstoS3Bucket(s3Client, config.remoteStateConfigS3.Bucket, config, terragruntOptions); err != nil { return err } } @@ -472,6 +478,15 @@ if err := EnableAccessLoggingForS3BucketWide(s3Client, &config.remoteStateConfigS3, terragruntOptions, config.AccessLoggingBucketName, config.AccessLoggingTargetPrefix); err != nil { return err } + + if err := EnableSSEForS3BucketWide(s3Client, config.AccessLoggingBucketName, config, terragruntOptions); err != nil { + return err + } + + if err := EnableEnforcedTLSAccesstoS3Bucket(s3Client, config.AccessLoggingBucketName, config, terragruntOptions); err != nil { + return err + } + } else { terragruntOptions.Logger.Debugf("Access Logging is disabled for the remote state AWS S3 bucket %s", config.remoteStateConfigS3.Bucket) } @@ -628,7 +643,7 @@ if config.SkipBucketEnforcedTLS { terragruntOptions.Logger.Debugf("TLS enforcement is disabled for the remote state S3 bucket %s using 'skip_bucket_enforced_tls' config.", config.remoteStateConfigS3.Bucket) - } else if err := EnableEnforcedTLSAccesstoS3Bucket(s3Client, config, terragruntOptions); err != nil { + } else if err := EnableEnforcedTLSAccesstoS3Bucket(s3Client, config.remoteStateConfigS3.Bucket, config, terragruntOptions); err != nil { return err } @@ -650,7 +665,7 @@ if config.SkipBucketSSEncryption { terragruntOptions.Logger.Debugf("Server-Side Encryption is disabled for the remote state AWS S3 bucket %s using 'skip_bucket_ssencryption' config.", config.remoteStateConfigS3.Bucket) - } else if err := EnableSSEForS3BucketWide(s3Client, config, terragruntOptions); err != nil { + } else if err := EnableSSEForS3BucketWide(s3Client, config.remoteStateConfigS3.Bucket, config, terragruntOptions); err != nil { return err } @@ -673,6 +688,14 @@ if err := EnableAccessLoggingForS3BucketWide(s3Client, &config.remoteStateConfigS3, terragruntOptions, config.AccessLoggingBucketName, config.AccessLoggingTargetPrefix); err != nil { return err } + + if err := EnableSSEForS3BucketWide(s3Client, config.AccessLoggingBucketName, config, terragruntOptions); err != nil { + return err + } + + if err := EnableEnforcedTLSAccesstoS3Bucket(s3Client, config.AccessLoggingBucketName, config, terragruntOptions); err != nil { + return err + } } else { terragruntOptions.Logger.Debugf("Access Logging is disabled for the remote state AWS S3 bucket %s", config.remoteStateConfigS3.Bucket) } @@ -885,8 +908,7 @@ } // Add a policy to enforce TLS based access to the bucket -func EnableEnforcedTLSAccesstoS3Bucket(s3Client *s3.S3, config *ExtendedRemoteStateConfigS3, terragruntOptions *options.TerragruntOptions) error { - bucket := config.remoteStateConfigS3.Bucket +func EnableEnforcedTLSAccesstoS3Bucket(s3Client *s3.S3, bucket string, config *ExtendedRemoteStateConfigS3, terragruntOptions *options.TerragruntOptions) error { terragruntOptions.Logger.Debugf("Enabling enforced TLS access for S3 bucket %s", bucket) partition, err := aws_helper.GetAWSPartition(config.GetAwsSessionConfig(), terragruntOptions) @@ -1017,8 +1039,8 @@ } // Enable bucket-wide Server-Side Encryption for the AWS S3 bucket specified in the given config -func EnableSSEForS3BucketWide(s3Client *s3.S3, config *ExtendedRemoteStateConfigS3, terragruntOptions *options.TerragruntOptions) error { - terragruntOptions.Logger.Debugf("Enabling bucket-wide SSE on AWS S3 bucket %s", config.remoteStateConfigS3.Bucket) +func EnableSSEForS3BucketWide(s3Client *s3.S3, bucketName string, config *ExtendedRemoteStateConfigS3, terragruntOptions *options.TerragruntOptions) error { + terragruntOptions.Logger.Debugf("Enabling bucket-wide SSE on AWS S3 bucket %s", bucketName) accountID, err := aws_helper.GetAWSAccountID(config.GetAwsSessionConfig(), terragruntOptions) if err != nil { @@ -1049,14 +1071,14 @@ rule := &s3.ServerSideEncryptionRule{ApplyServerSideEncryptionByDefault: defEnc} rules := []*s3.ServerSideEncryptionRule{rule} serverConfig := &s3.ServerSideEncryptionConfiguration{Rules: rules} - input := &s3.PutBucketEncryptionInput{Bucket: aws.String(config.remoteStateConfigS3.Bucket), ServerSideEncryptionConfiguration: serverConfig} + input := &s3.PutBucketEncryptionInput{Bucket: aws.String(bucketName), ServerSideEncryptionConfiguration: serverConfig} _, err = s3Client.PutBucketEncryption(input) if err != nil { return errors.WithStackTrace(err) } - terragruntOptions.Logger.Debugf("Enabled bucket-wide SSE on AWS S3 bucket %s", config.remoteStateConfigS3.Bucket) + terragruntOptions.Logger.Debugf("Enabled bucket-wide SSE on AWS S3 bucket %s", bucketName) return nil } @@ -1331,3 +1353,11 @@ func (err MaxRetriesWaitingForS3ACLExceeded) Error() string { return fmt.Sprintf("Exceeded max retries waiting for bucket S3 bucket %s to have proper ACL for access logging", string(err)) } + +type InvalidAccessLoggingBucketEncryption struct { + BucketSSEAlgorithm string +} + +func (err InvalidAccessLoggingBucketEncryption) Error() string { + return fmt.Sprintf("Encryption algorithm %s is not supported for access logging bucket. Please use AES256", err.BucketSSEAlgorithm) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/.gitignore new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/.gitignore --- old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/.gitignore 2022-11-29 13:32:50.000000000 +0100 @@ -0,0 +1 @@ +backend.tf diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/main.tf new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/main.tf --- old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/main.tf 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/main.tf 2022-11-29 13:32:50.000000000 +0100 @@ -0,0 +1 @@ +resource "null_resource" "foo" {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/remote_terragrunt.hcl new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/remote_terragrunt.hcl --- old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/remote_terragrunt.hcl 1970-01-01 01:00:00.000000000 +0100 +++ new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/invlid-configuration/remote_terragrunt.hcl 2022-11-29 13:32:50.000000000 +0100 @@ -0,0 +1,18 @@ +# Configure Terragrunt to automatically store tfstate files in an S3 bucket +remote_state { + backend = "s3" + generate = { + path = "backend.tf" + if_exists = "overwrite" + } + config = { + encrypt = true + bucket = "__FILL_IN_BUCKET_NAME__" + key = "terraform.tfstate" + region = "us-west-2" + dynamodb_table = "__FILL_IN_LOCK_TABLE_NAME__" + enable_lock_table_ssencryption = true + accesslogging_bucket_name = "__FILL_IN_LOGS_BUCKET_NAME__" + bucket_sse_algorithm = "aws:kms" + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/no-target-prefix-input/remote_terragrunt.hcl new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/no-target-prefix-input/remote_terragrunt.hcl --- old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/no-target-prefix-input/remote_terragrunt.hcl 2022-11-24 18:43:36.000000000 +0100 +++ new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/no-target-prefix-input/remote_terragrunt.hcl 2022-11-29 13:32:50.000000000 +0100 @@ -13,5 +13,6 @@ dynamodb_table = "__FILL_IN_LOCK_TABLE_NAME__" enable_lock_table_ssencryption = true accesslogging_bucket_name = "__FILL_IN_LOGS_BUCKET_NAME__" + bucket_sse_algorithm = "AES256" } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/with-target-prefix-input/remote_terragrunt.hcl new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/with-target-prefix-input/remote_terragrunt.hcl --- old/terragrunt-0.41.0/test/fixture-regressions/accesslogging-bucket/with-target-prefix-input/remote_terragrunt.hcl 2022-11-24 18:43:36.000000000 +0100 +++ new/terragrunt-0.42.0/test/fixture-regressions/accesslogging-bucket/with-target-prefix-input/remote_terragrunt.hcl 2022-11-29 13:32:50.000000000 +0100 @@ -14,5 +14,6 @@ enable_lock_table_ssencryption = true accesslogging_bucket_name = "__FILL_IN_LOGS_BUCKET_NAME__" accesslogging_target_prefix = "logs/" + bucket_sse_algorithm = "AES256" } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terragrunt-0.41.0/test/integration_test.go new/terragrunt-0.42.0/test/integration_test.go --- old/terragrunt-0.41.0/test/integration_test.go 2022-11-24 18:43:36.000000000 +0100 +++ new/terragrunt-0.42.0/test/integration_test.go 2022-11-29 13:32:50.000000000 +0100 @@ -601,6 +601,32 @@ assert.Equal(t, s3BucketLogsName, targetLoggingBucket) assert.Equal(t, s3BucketLogsTargetPrefix, targetLoggingBucketPrefix) + + encryptionConfig, err := bucketEncryption(t, TERRAFORM_REMOTE_STATE_S3_REGION, targetLoggingBucket) + assert.NoError(t, err) + assert.NotNil(t, encryptionConfig) + assert.NotNil(t, encryptionConfig.ServerSideEncryptionConfiguration) + for _, rule := range encryptionConfig.ServerSideEncryptionConfiguration.Rules { + if rule.ApplyServerSideEncryptionByDefault != nil { + if rule.ApplyServerSideEncryptionByDefault.SSEAlgorithm != nil { + assert.Equal(t, s3.ServerSideEncryptionAes256, *rule.ApplyServerSideEncryptionByDefault.SSEAlgorithm) + } + } + } + + policy, err := bucketPolicy(t, TERRAFORM_REMOTE_STATE_S3_REGION, targetLoggingBucket) + assert.NoError(t, err) + assert.NotNil(t, policy.Policy) + + policyInBucket, err := aws_helper.UnmarshalPolicy(*policy.Policy) + assert.NoError(t, err) + enforceSSE := false + for _, statement := range policyInBucket.Statement { + if statement.Sid == remote.SidEnforcedTLSPolicy { + enforceSSE = true + } + } + assert.True(t, enforceSSE) } // Regression test to ensure that `accesslogging_bucket_name` is taken into account @@ -635,6 +661,28 @@ assert.Equal(t, remote.DefaultS3BucketAccessLoggingTargetPrefix, targetLoggingBucketPrefix) } +func TestTerragruntFailWithInvalidLoggingConfiguration(t *testing.T) { + t.Parallel() + + examplePath := filepath.Join(TEST_FIXTURE_REGRESSIONS, "accesslogging-bucket/invlid-configuration") + cleanupTerraformFolder(t, examplePath) + + s3BucketName := fmt.Sprintf("terragrunt-test-bucket-%s", strings.ToLower(uniqueId())) + lockTableName := fmt.Sprintf("terragrunt-test-locks-%s", strings.ToLower(uniqueId())) + + tmpTerragruntConfigPath := createTmpTerragruntConfig( + t, + examplePath, + s3BucketName, + lockTableName, + "remote_terragrunt.hcl", + ) + + _, _, err := runTerragruntCommandWithOutput(t, fmt.Sprintf("terragrunt validate --terragrunt-non-interactive --terragrunt-config %s --terragrunt-working-dir %s", tmpTerragruntConfigPath, examplePath)) + assert.Error(t, err) + assert.Contains(t, err.Error(), s3.ServerSideEncryptionAes256) +} + func TestTerragruntWorksWithGCSBackend(t *testing.T) { t.Parallel() @@ -4107,6 +4155,56 @@ return nil } +func bucketEncryption(t *testing.T, awsRegion string, bucketName string) (*s3.GetBucketEncryptionOutput, error) { + mockOptions, err := options.NewTerragruntOptionsForTest("integration_test") + if err != nil { + t.Logf("Error creating mockOptions: %v", err) + return nil, err + } + + sessionConfig := &aws_helper.AwsSessionConfig{ + Region: awsRegion, + } + + s3Client, err := remote.CreateS3Client(sessionConfig, mockOptions) + if err != nil { + t.Logf("Error creating S3 client: %v", err) + return nil, err + } + + input := &s3.GetBucketEncryptionInput{Bucket: aws.String(bucketName)} + output, err := s3Client.GetBucketEncryption(input) + if err != nil { + return nil, nil + } + + return output, nil +} + +func bucketPolicy(t *testing.T, awsRegion string, bucketName string) (*s3.GetBucketPolicyOutput, error) { + mockOptions, err := options.NewTerragruntOptionsForTest("integration_test") + if err != nil { + t.Logf("Error creating mockOptions: %v", err) + return nil, err + } + + sessionConfig := &aws_helper.AwsSessionConfig{ + Region: awsRegion, + } + + s3Client, err := remote.CreateS3Client(sessionConfig, mockOptions) + if err != nil { + return nil, err + } + policyOutput, err := s3Client.GetBucketPolicy(&s3.GetBucketPolicyInput{ + Bucket: aws.String(bucketName), + }) + if err != nil { + return nil, err + } + return policyOutput, nil +} + // Create an authenticated client for DynamoDB func createDynamoDbClient(awsRegion, awsProfile string, iamRoleArn string) (*dynamodb.DynamoDB, error) { mockOptions, err := options.NewTerragruntOptionsForTest("integration_test") ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/terragrunt/vendor.tar.gz /work/SRC/openSUSE:Factory/.terragrunt.new.1597/vendor.tar.gz differ: char 5, line 1