Skip to content

Commit 3cc330a

Browse files
authored
feat: function rules (#11)
* feat: function rules * main branch for linter * Add lint to makefile * Format makefile * lint ---------
1 parent 5c79115 commit 3cc330a

28 files changed

+1397
-86
lines changed

.github/workflows/lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ name: lint
33
on:
44
push:
55
branches:
6-
- master
6+
- main
77
pull_request:
88
branches:
9-
- master
9+
- main
1010

1111
jobs:
1212
checks:

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ build:
99
install: build
1010
mkdir -p ~/.tflint.d/plugins
1111
mv ./tflint-ruleset-azurerm-security ~/.tflint.d/plugins
12+
13+
lint:
14+
golint --set_exit_status $$(go list ./...)
15+
go vet ./...
16+
17+
tools:
18+
go install golang.org/x/lint/golint@latest

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ You can install the plugin with `tflint --init`. Declare a config in `.tflint.hc
1616
plugin "azurerm-security" {
1717
enabled = true
1818
19-
version = "0.1.2"
19+
version = "0.1.3"
2020
source = "github.com/pregress/tflint-ruleset-azurerm-security"
2121
}
2222
```

docs/README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,46 @@
11
# Rules
22

3+
## azurerm_key_vault
34
|Name|Description|Severity|Enabled|Link|
45
| --- | --- | --- | --- | --- |
56
|azurerm_key_vault_public_network_access_enabled|Consider disabling public network access on keyvaults. |NOTICE|||
7+
8+
## azurerm_linux_function_app
9+
|Name|Description|Severity|Enabled|Link|
10+
| --- | --- | --- | --- | --- |
11+
|azurerm_linux_function_app_ftps_state|Disable sftp to a linux function app |WARNING|||
12+
|azurerm_linux_function_app_https_only|Force all traffic over https |WARNING|||
13+
|azurerm_linux_function_app_minimum_tls_version|Enforce TLS 1.2 on linux function apps |WARNING|||
14+
15+
## azurerm_linux_web_app
16+
|Name|Description|Severity|Enabled|Link|
17+
| --- | --- | --- | --- | --- |
618
|azurerm_linux_web_app_ftps_state|Disable sftp to a linux web app |WARNING|||
719
|azurerm_linux_web_app_https_only|Force all traffic over https |WARNING|||
820
|azurerm_linux_web_app_minimum_tls_version|Enforce TLS 1.2 on linux web apps |WARNING|||
21+
22+
## azurerm_mssql_database
23+
|Name|Description|Severity|Enabled|Link|
24+
| --- | --- | --- | --- | --- |
925
|azurerm_mssql_database_transparent_data_encryption_enabled|Enforce transparant data encryption|WARNING|||
26+
27+
## azurerm_storage_account
28+
|Name|Description|Severity|Enabled|Link|
29+
| --- | --- | --- | --- | --- |
1030
|azurerm_storage_account_public_network_access_enabled|Consider disabling public network access on storage accounts. |NOTICE|||
1131
|azurerm_storage_account_tls_version|Enforce TLS 1.2 on storage accounts |WARNING|||
32+
33+
## azurerm_windows_function_app
34+
|Name|Description|Severity|Enabled|Link|
35+
| --- | --- | --- | --- | --- |
36+
|azurerm_windows_function_app_ftps_state|Disable sftp to a windows function app |WARNING|||
37+
|azurerm_windows_function_app_https_only|Force all traffic over https |WARNING|||
38+
|azurerm_windows_function_app_minimum_tls_version|Enforce TLS 1.2 on windows function apps |WARNING|||
39+
40+
41+
## azurerm_windows_web_app
42+
|Name|Description|Severity|Enabled|Link|
43+
| --- | --- | --- | --- | --- |
1244
|azurerm_windows_web_app_ftps_state|Disable sftp to a windows web app |WARNING|||
1345
|azurerm_windows_web_app_https_only|Force all traffic over https |WARNING|||
14-
|azurerm_windows_web_app_minimum_tls_version|Enforce TLS 1.2 on windows web apps |WARNING|||
46+
|azurerm_windows_web_app_minimum_tls_version|Enforce TLS 1.2 on windows web apps |WARNING|||

main.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,33 @@ import (
77
"github.com/terraform-linters/tflint-ruleset-azurerm-security/rules"
88
)
99

10-
func CreateRuleSet() *tflint.BuiltinRuleSet {
10+
func createRuleSet() *tflint.BuiltinRuleSet {
1111
return &tflint.BuiltinRuleSet{
1212
Name: "azurerm-security",
13-
Version: "0.1.2",
13+
Version: "0.1.3",
1414
Rules: []tflint.Rule{
1515
rules.NewAzurermKeyVaultPublicNetworkAccessEnabled(),
16+
rules.NewAzurermLinuxFunctionAppFtpsState(),
17+
rules.NewAzurermLinuxFunctionAppHTTPSOnly(),
18+
rules.NewAzurermLinuxFunctionAppMinimumTLSVersion(),
1619
rules.NewAzurermLinuxWebAppFtpsState(),
17-
rules.NewAzurermLinuxWebAppHttpsOnly(),
18-
rules.NewAzurermLinuxWebAppMinimumTlsVersion(),
20+
rules.NewAzurermLinuxWebAppHTTPSOnly(),
21+
rules.NewAzurermLinuxWebAppMinimumTLSVersion(),
1922
rules.NewAzurermMssqlDatabaseEncryption(),
2023
rules.NewAzurermStorageAccountPublicNetworkAccessEnabled(),
21-
rules.NewAzurermStorageAccountUnsecureTls(),
24+
rules.NewAzurermStorageAccountUnsecureTLS(),
25+
rules.NewAzurermWindowsFunctionAppFtpsState(),
26+
rules.NewAzurermWindowsFunctionAppHTTPSOnly(),
27+
rules.NewAzurermWindowsFunctionAppMinimumTLSVersion(),
2228
rules.NewAzurermWindowsWebAppFtpsState(),
23-
rules.NewAzurermWindowsWebAppHttpsOnly(),
24-
rules.NewAzurermWindowsWebAppMinimumTlsVersion(),
29+
rules.NewAzurermWindowsWebAppHTTPSOnly(),
30+
rules.NewAzurermWindowsWebAppMinimumTLSVersion(),
2531
},
2632
}
2733
}
2834

2935
func main() {
3036
plugin.Serve(&plugin.ServeOpts{
31-
RuleSet: CreateRuleSet(),
37+
RuleSet: createRuleSet(),
3238
})
3339
}

main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
func TestRulesLength(t *testing.T) {
12-
ruleSet := CreateRuleSet()
12+
ruleSet := createRuleSet()
1313
actualRules := len(ruleSet.Rules)
1414

1515
// Count .go files in rules directory that don't end with _test.go
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package rules
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/terraform-linters/tflint-plugin-sdk/hclext"
8+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
9+
)
10+
11+
// AzurermLinuxFunctionAppFtpsState checks that ftps_state is set to "Disabled"
12+
type AzurermLinuxFunctionAppFtpsState struct {
13+
tflint.DefaultRule
14+
15+
resourceType string
16+
attributePath []string
17+
expectedValue string
18+
}
19+
20+
// NewAzurermLinuxFunctionAppFtpsState returns a new rule instance
21+
func NewAzurermLinuxFunctionAppFtpsState() *AzurermLinuxFunctionAppFtpsState {
22+
return &AzurermLinuxFunctionAppFtpsState{
23+
resourceType: "azurerm_linux_function_app",
24+
attributePath: []string{"site_config", "ftps_state"},
25+
expectedValue: "Disabled",
26+
}
27+
}
28+
29+
// Name returns the rule name
30+
func (r *AzurermLinuxFunctionAppFtpsState) Name() string {
31+
return "azurerm_linux_function_app_ftps_state"
32+
}
33+
34+
// Enabled returns whether the rule is enabled by default
35+
func (r *AzurermLinuxFunctionAppFtpsState) Enabled() bool {
36+
return true
37+
}
38+
39+
// Severity returns the rule severity
40+
func (r *AzurermLinuxFunctionAppFtpsState) Severity() tflint.Severity {
41+
return tflint.WARNING
42+
}
43+
44+
// Link returns the rule reference link
45+
func (r *AzurermLinuxFunctionAppFtpsState) Link() string {
46+
return ""
47+
}
48+
49+
// Check verifies that ftps_state is set to "Disabled"
50+
func (r *AzurermLinuxFunctionAppFtpsState) Check(runner tflint.Runner) error {
51+
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{
52+
Blocks: []hclext.BlockSchema{
53+
{
54+
Type: "site_config",
55+
Body: &hclext.BodySchema{
56+
Attributes: []hclext.AttributeSchema{
57+
{Name: "ftps_state"},
58+
},
59+
},
60+
},
61+
},
62+
}, nil)
63+
if err != nil {
64+
return err
65+
}
66+
67+
for _, resource := range resources.Blocks {
68+
siteConfigBlocks := resource.Body.Blocks.OfType("site_config")
69+
if len(siteConfigBlocks) == 0 {
70+
runner.EmitIssue(
71+
r,
72+
"site_config block is missing, ftps_state should be set to Disabled",
73+
resource.DefRange,
74+
)
75+
continue
76+
}
77+
78+
siteConfig := siteConfigBlocks[0]
79+
attribute, exists := siteConfig.Body.Attributes["ftps_state"]
80+
if !exists {
81+
runner.EmitIssue(
82+
r,
83+
"ftps_state is missing in site_config, should be set to Disabled",
84+
siteConfig.DefRange,
85+
)
86+
continue
87+
}
88+
89+
err := runner.EvaluateExpr(attribute.Expr, func(val string) error {
90+
if !strings.EqualFold(val, r.expectedValue) {
91+
runner.EmitIssue(
92+
r,
93+
fmt.Sprintf("ftps_state is set to %s, should be set to Disabled", val),
94+
attribute.Expr.Range(),
95+
)
96+
}
97+
return nil
98+
}, nil)
99+
if err != nil {
100+
return err
101+
}
102+
}
103+
104+
return nil
105+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package rules
2+
3+
import (
4+
"testing"
5+
6+
hcl "github.com/hashicorp/hcl/v2"
7+
"github.com/terraform-linters/tflint-plugin-sdk/helper"
8+
)
9+
10+
func Test_AzurermLinuxFunctionAppFtpsState(t *testing.T) {
11+
tests := []struct {
12+
Name string
13+
Content string
14+
Expected helper.Issues
15+
}{
16+
{
17+
Name: "ftps_state not set to Disabled",
18+
Content: `
19+
resource "azurerm_linux_function_app" "example" {
20+
site_config {
21+
ftps_state = "FtpsOnly"
22+
}
23+
}`,
24+
Expected: helper.Issues{
25+
{
26+
Rule: NewAzurermLinuxFunctionAppFtpsState(),
27+
Message: "ftps_state is set to FtpsOnly, should be set to Disabled",
28+
Range: hcl.Range{
29+
Filename: "resource.tf",
30+
Start: hcl.Pos{
31+
Line: 4,
32+
Column: 22,
33+
},
34+
End: hcl.Pos{
35+
Line: 4,
36+
Column: 32,
37+
},
38+
},
39+
},
40+
},
41+
},
42+
{
43+
Name: "ftps_state set to disabled (lowercase)",
44+
Content: `
45+
resource "azurerm_linux_function_app" "example" {
46+
site_config {
47+
ftps_state = "disabled"
48+
}
49+
}`,
50+
Expected: helper.Issues{},
51+
},
52+
{
53+
Name: "ftps_state set to DISABLED (uppercase)",
54+
Content: `
55+
resource "azurerm_linux_function_app" "example" {
56+
site_config {
57+
ftps_state = "DISABLED"
58+
}
59+
}`,
60+
Expected: helper.Issues{},
61+
},
62+
{
63+
Name: "ftps_state attribute missing",
64+
Content: `
65+
resource "azurerm_linux_function_app" "example" {
66+
site_config {
67+
}
68+
}`,
69+
Expected: helper.Issues{
70+
{
71+
Rule: NewAzurermLinuxFunctionAppFtpsState(),
72+
Message: "ftps_state is missing in site_config, should be set to Disabled",
73+
Range: hcl.Range{
74+
Filename: "resource.tf",
75+
Start: hcl.Pos{
76+
Line: 3,
77+
Column: 5,
78+
},
79+
End: hcl.Pos{
80+
Line: 3,
81+
Column: 16,
82+
},
83+
},
84+
},
85+
},
86+
},
87+
{
88+
Name: "site_config block missing",
89+
Content: `
90+
resource "azurerm_linux_function_app" "example" {
91+
}`,
92+
Expected: helper.Issues{
93+
{
94+
Rule: NewAzurermLinuxFunctionAppFtpsState(),
95+
Message: "site_config block is missing, ftps_state should be set to Disabled",
96+
Range: hcl.Range{
97+
Filename: "resource.tf",
98+
Start: hcl.Pos{
99+
Line: 2,
100+
Column: 1,
101+
},
102+
End: hcl.Pos{
103+
Line: 2,
104+
Column: 48,
105+
},
106+
},
107+
},
108+
},
109+
},
110+
}
111+
112+
rule := NewAzurermLinuxFunctionAppFtpsState()
113+
114+
for _, test := range tests {
115+
t.Run(test.Name, func(t *testing.T) {
116+
runner := helper.TestRunner(t, map[string]string{"resource.tf": test.Content})
117+
118+
if err := rule.Check(runner); err != nil {
119+
t.Fatalf("Unexpected error occurred: %s", err)
120+
}
121+
122+
helper.AssertIssues(t, test.Expected, runner.Issues)
123+
})
124+
}
125+
}

0 commit comments

Comments
 (0)