diff --git a/docs/rules/aws_s3_bucket_name.md b/docs/rules/aws_s3_bucket_name.md index 4280a7f9..49fe8437 100644 --- a/docs/rules/aws_s3_bucket_name.md +++ b/docs/rules/aws_s3_bucket_name.md @@ -21,21 +21,30 @@ rule "aws_s3_bucket_name" { resource "aws_s3_bucket" "foo" { bucket = "foo" } + +resource "aws_s3_bucket" "too_long" { + bucket = "a-really-ultra-hiper-super-long-foo-bar-baz-bucket-name.domain.test" +} ``` ```sh $ tflint -1 issue(s) found: +2 issue(s) found: -Warning: Bucket name "foo" does not have prefix "my-org" (aws_s3_bucket_name) +Error: Bucket name "foo" does not have prefix "my-org" (aws_s3_bucket_name) on main.tf line 2: 2: bucket = "foo" + +Error: Bucket name "a-really-ultra-hiper-super-long-foo-bar-baz-bucket-name.domain.test" length must be within 3 - 63 character range (aws_s3_bucket_name) + + on main.tf line 2: + 2: bucket = "a-really-ultra-hiper-super-long-foo-bar-baz-bucket-name.domain.test" ``` ## Why -Amazon S3 bucket names must be globally unique and have [restrictive naming rules](https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html#bucketnamingrules). +Amazon S3 bucket names must be globally unique and have [restrictive naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html). * Prefixing bucket names with an organization name can help avoid naming conflicts * You may wish to enforce other naming conventions (e.g., disallowing dots) diff --git a/integration/rule-config/result.json b/integration/rule-config/result.json index 17a78b54..d5de695e 100644 --- a/integration/rule-config/result.json +++ b/integration/rule-config/result.json @@ -3,7 +3,7 @@ { "rule": { "name": "aws_s3_bucket_name", - "severity": "warning", + "severity": "error", "link": "https://github.com/terraform-linters/tflint-ruleset-aws/blob/v0.27.0/docs/rules/aws_s3_bucket_name.md" }, "message": "Bucket name \"foo_bar\" does not match regex \"^[a-z\\-]+$\"", diff --git a/rules/aws_s3_bucket_name.go b/rules/aws_s3_bucket_name.go index 3fc86663..e96ef277 100644 --- a/rules/aws_s3_bucket_name.go +++ b/rules/aws_s3_bucket_name.go @@ -38,12 +38,12 @@ func (r *AwsS3BucketNameRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *AwsS3BucketNameRule) Enabled() bool { - return false + return true } // Severity returns the rule severity func (r *AwsS3BucketNameRule) Severity() tflint.Severity { - return tflint.WARNING + return tflint.ERROR } // Link returns the rule reference link @@ -51,7 +51,7 @@ func (r *AwsS3BucketNameRule) Link() string { return project.ReferenceLink(r.Name()) } -// Check if the name of the s3 bucket matches the regex defined in the rule +// Check if the name of the s3 bucket is valid func (r *AwsS3BucketNameRule) Check(runner tflint.Runner) error { config := awsS3BucketNameConfig{} if err := runner.DecodeRuleConfig(r.Name(), &config); err != nil { @@ -70,6 +70,9 @@ func (r *AwsS3BucketNameRule) Check(runner tflint.Runner) error { return err } + bucketNameMinLength := 3 + bucketNameMaxLength := 63 + for _, resource := range resources.Blocks { attribute, exists := resource.Body.Attributes[r.attributeName] if !exists { @@ -96,6 +99,14 @@ func (r *AwsS3BucketNameRule) Check(runner tflint.Runner) error { ) } } + + if len(name) < bucketNameMinLength || len(name) > bucketNameMaxLength { + runner.EmitIssue( + r, + fmt.Sprintf("Bucket name %q must be between %d and %d characters", name, bucketNameMinLength, bucketNameMaxLength), + attribute.Expr.Range(), + ) + } return nil }, nil) if err != nil { diff --git a/rules/aws_s3_bucket_name_test.go b/rules/aws_s3_bucket_name_test.go index 7fde61b2..8f3873f6 100644 --- a/rules/aws_s3_bucket_name_test.go +++ b/rules/aws_s3_bucket_name_test.go @@ -117,6 +117,25 @@ rule "aws_s3_bucket_name" { }, }, }, + { + Name: "length", + Content: ` +resource "aws_s3_bucket" "too_long" { + bucket = "a-really-ultra-hiper-super-long-foo-bar-baz-bucket-name.domain.test" +} +`, + Expected: helper.Issues{ + { + Rule: NewAwsS3BucketNameRule(), + Message: `Bucket name "a-really-ultra-hiper-super-long-foo-bar-baz-bucket-name.domain.test" must be between 3 and 63 characters`, + Range: hcl.Range{ + Filename: "resource.tf", + Start: hcl.Pos{Line: 3, Column: 12}, + End: hcl.Pos{Line: 3, Column: 81}, + }, + }, + }, + }, } rule := NewAwsS3BucketNameRule()