From 46c68b8bef8ead822bed4a99b5adc865aba15079 Mon Sep 17 00:00:00 2001 From: Amanda Kaufman Date: Tue, 25 Aug 2020 09:12:32 -0600 Subject: [PATCH 1/5] Add custom rule for storage account names --- rules/azurerm_storage_account_invalid_name.go | 65 +++++++++++++++++++ rules/provider.go | 16 +++++ 2 files changed, 81 insertions(+) create mode 100644 rules/azurerm_storage_account_invalid_name.go diff --git a/rules/azurerm_storage_account_invalid_name.go b/rules/azurerm_storage_account_invalid_name.go new file mode 100644 index 00000000..9d2d449f --- /dev/null +++ b/rules/azurerm_storage_account_invalid_name.go @@ -0,0 +1,65 @@ +package rules + +import ( + "fmt" + "regexp" + + hcl "github.com/hashicorp/hcl/v2" + "github.com/terraform-linters/tflint-plugin-sdk/tflint" + "github.com/terraform-linters/tflint-ruleset-azurerm/project" +) + +// AzurermStorageAccountInvalidNameRule checks the pattern is valid +type AzurermStorageAccountInvalidNameRule struct { + resourceType string + attributeName string + pattern *regexp.Regexp +} + +// NewAzurermStorageAccountInvalidNameRule returns new rule with default attributes +func NewAzurermStorageAccountInvalidNameRule() *AzurermStorageAccountInvalidNameRule { + return &AzurermStorageAccountInvalidNameRule{ + resourceType: "azurerm_storage_account", + attributeName: "name", + pattern: regexp.MustCompile(`^[a-z]{3, 24}$`), + } +} + +// Name returns the rule name +func (r *AzurermStorageAccountInvalidNameRule) Name() string { + return "azurerm_storage_account_invalid_name" +} + +// Enabled returns whether the rule is enabled by default +func (r *AzurermStorageAccountInvalidNameRule) Enabled() bool { + return true +} + +// Severity returns the rule severity +func (r *AzurermStorageAccountInvalidNameRule) Severity() string { + return tflint.ERROR +} + +// Link returns the rule reference link +func (r *AzurermStorageAccountInvalidNameRule) Link() string { + return project.ReferenceLink(r.Name()) +} + +// Check checks the pattern is valid +func (r *AzurermStorageAccountInvalidNameRule) Check(runner tflint.Runner) error { + return runner.WalkResourceAttributes(r.resourceType, r.attributeName, func(attribute *hcl.Attribute) error { + var val string + err := runner.EvaluateExpr(attribute.Expr, &val) + + return runner.EnsureNoError(err, func() error { + if !r.pattern.MatchString(val) { + runner.EmitIssueOnExpr( + r, + fmt.Sprintf(`"%s" does not match valid pattern %s`, truncateLongMessage(val), `^[a-z]{3, 24}$`), + attribute.Expr, + ) + } + return nil + }) + }) +} diff --git a/rules/provider.go b/rules/provider.go index d84ab3c8..a3740bb5 100644 --- a/rules/provider.go +++ b/rules/provider.go @@ -1,6 +1,8 @@ package rules import ( + "strings" + "github.com/terraform-linters/tflint-plugin-sdk/tflint" "github.com/terraform-linters/tflint-ruleset-azurerm/rules/apispec" ) @@ -13,3 +15,17 @@ var Rules = append([]tflint.Rule{ NewAzurermWindowsVirtualMachineInvalidSizeRule(), NewAzurermWindowsVirtualMachineScaleSetInvalidSkuRule(), }, apispec.Rules...) + +func truncateLongMessage(str string) string { + limit := 80 + + str = strings.Replace(str, "\r\n", "\n", -1) + str = strings.Replace(str, "\n", "\\n", -1) + + r := []rune(str) + if len(r) > limit { + return string(r[0:limit]) + "..." + } + + return str +} From 8fe6153425ea952dd75d1dcec19250bdfbae1156 Mon Sep 17 00:00:00 2001 From: Amanda Kaufman Date: Tue, 25 Aug 2020 11:43:49 -0600 Subject: [PATCH 2/5] Add storage account name rule to provider.go --- rules/provider.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/provider.go b/rules/provider.go index a3740bb5..175e1378 100644 --- a/rules/provider.go +++ b/rules/provider.go @@ -11,6 +11,7 @@ import ( var Rules = append([]tflint.Rule{ NewAzurermLinuxVirtualMachineInvalidSizeRule(), NewAzurermLinuxVirtualMachineScaleSetInvalidSkuRule(), + NewAzurermStorageAccountInvalidNameRule(), NewAzurermVirtualMachineInvalidVMSizeRule(), NewAzurermWindowsVirtualMachineInvalidSizeRule(), NewAzurermWindowsVirtualMachineScaleSetInvalidSkuRule(), From dd9e3ac055ddc3a5e4d5101793e7a0ea4de8fbd7 Mon Sep 17 00:00:00 2001 From: Amanda Kaufman Date: Tue, 25 Aug 2020 11:44:21 -0600 Subject: [PATCH 3/5] Fix broken regex --- rules/azurerm_storage_account_invalid_name.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/azurerm_storage_account_invalid_name.go b/rules/azurerm_storage_account_invalid_name.go index 9d2d449f..5d4a7eea 100644 --- a/rules/azurerm_storage_account_invalid_name.go +++ b/rules/azurerm_storage_account_invalid_name.go @@ -21,7 +21,7 @@ func NewAzurermStorageAccountInvalidNameRule() *AzurermStorageAccountInvalidName return &AzurermStorageAccountInvalidNameRule{ resourceType: "azurerm_storage_account", attributeName: "name", - pattern: regexp.MustCompile(`^[a-z]{3, 24}$`), + pattern: regexp.MustCompile(`^[a-z0-9]{3,24}$`), } } @@ -55,7 +55,7 @@ func (r *AzurermStorageAccountInvalidNameRule) Check(runner tflint.Runner) error if !r.pattern.MatchString(val) { runner.EmitIssueOnExpr( r, - fmt.Sprintf(`"%s" does not match valid pattern %s`, truncateLongMessage(val), `^[a-z]{3, 24}$`), + fmt.Sprintf(`"%s" does not match valid pattern %s`, truncateLongMessage(val), `^[a-z0-9]{3,24}$`), attribute.Expr, ) } From db1ebfc2d7c94a40a6d7e7e56c7da20a5e64afaa Mon Sep 17 00:00:00 2001 From: Amanda Kaufman Date: Tue, 25 Aug 2020 11:46:14 -0600 Subject: [PATCH 4/5] Add .md file to docs folder for new rule: azurerm_storage_account_invalid_name --- .../azurerm_storage_account_invalid_name.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 docs/rules/azurerm_storage_account_invalid_name.md diff --git a/docs/rules/azurerm_storage_account_invalid_name.md b/docs/rules/azurerm_storage_account_invalid_name.md new file mode 100644 index 00000000..69530490 --- /dev/null +++ b/docs/rules/azurerm_storage_account_invalid_name.md @@ -0,0 +1,38 @@ +# azurerm_storage_account_invalid_name + +Warns about values that appear to be invalid based on [azure-rest-api-specs](https://github.com/Azure/azure-rest-api-specs). + +In this rule, the string must match the regular expression `^[a-z0-9]{3,24}$``. + +## Example + +```hcl +resource "azurerm_storage_account" "foo" { + name = ... // invalid value +} +``` + +``` +$ tflint +1 issue(s) found: + +Error: "..." does not match valid pattern ^[a-z0-9]{3,24}$ (azurerm_storage_account_invalid_name) + + on template.tf line 15: + 15: name = ... // invalid value + +Reference: https://github.com/terraform-linters/tflint-ruleset-azurerm/blob/v0.4.0/docs/rules/azurerm_storage_account_invalid_name.md + +``` + +## Why + +Requests containing invalid values will return an error when calling the API by `terraform apply`. + +## How to Fix + +Replace the warned value with a valid value. + +## Source + +https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftstorage \ No newline at end of file From 92becc8cfc2e2747977e8ddb1552f01d1a3e18f5 Mon Sep 17 00:00:00 2001 From: Amanda Kaufman Date: Wed, 26 Aug 2020 09:01:31 -0600 Subject: [PATCH 5/5] Remove duplicate copy of truncateLongMessage function from rules/provider.go --- rules/azurerm_storage_account_invalid_name.go | 2 +- rules/provider.go | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/rules/azurerm_storage_account_invalid_name.go b/rules/azurerm_storage_account_invalid_name.go index 5d4a7eea..df0525f0 100644 --- a/rules/azurerm_storage_account_invalid_name.go +++ b/rules/azurerm_storage_account_invalid_name.go @@ -55,7 +55,7 @@ func (r *AzurermStorageAccountInvalidNameRule) Check(runner tflint.Runner) error if !r.pattern.MatchString(val) { runner.EmitIssueOnExpr( r, - fmt.Sprintf(`"%s" does not match valid pattern %s`, truncateLongMessage(val), `^[a-z0-9]{3,24}$`), + fmt.Sprintf(`"%s" does not match valid pattern %s`, val, `^[a-z0-9]{3,24}$`), attribute.Expr, ) } diff --git a/rules/provider.go b/rules/provider.go index 175e1378..32f22ce5 100644 --- a/rules/provider.go +++ b/rules/provider.go @@ -1,8 +1,6 @@ package rules import ( - "strings" - "github.com/terraform-linters/tflint-plugin-sdk/tflint" "github.com/terraform-linters/tflint-ruleset-azurerm/rules/apispec" ) @@ -16,17 +14,3 @@ var Rules = append([]tflint.Rule{ NewAzurermWindowsVirtualMachineInvalidSizeRule(), NewAzurermWindowsVirtualMachineScaleSetInvalidSkuRule(), }, apispec.Rules...) - -func truncateLongMessage(str string) string { - limit := 80 - - str = strings.Replace(str, "\r\n", "\n", -1) - str = strings.Replace(str, "\n", "\\n", -1) - - r := []rune(str) - if len(r) > limit { - return string(r[0:limit]) + "..." - } - - return str -}