Skip to content

Commit

Permalink
Disable module inspection by default
Browse files Browse the repository at this point in the history
  • Loading branch information
wata727 committed Jun 27, 2019
1 parent 3faba26 commit b18d8e3
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 20 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Application Options:
--ignore-rule=RULE1,RULE2... Ignore rule names
--var-file=FILE1,FILE2... Terraform variable file names
--var='foo=bar' Set a Terraform variable
--module Inspect modules
--deep Enable deep check mode
--aws-access-key=ACCESS_KEY AWS access key used in deep check mode
--aws-secret-key=SECRET_KEY AWS secret key used in deep check mode
Expand All @@ -120,6 +121,7 @@ The config file is written in [HCL](https://github.com/hashicorp/hcl), and you c

```hcl
config {
module = true
deep_check = true
force = false
Expand Down Expand Up @@ -264,14 +266,14 @@ module "aws_instance" {
```

```
$ tflint
$ tflint --module
aws_instance/main.tf
ERROR:6 "t1.2xlarge" is invalid instance type. (aws_instance_invalid_type)
Result: 1 issues (1 errors , 0 warnings , 0 notices)
```

TFLint loads modules in the same way as Terraform. So note that you need to run `terraform init` first.
Module inspection is disabled by default. Inspection is enabled by running with the `--module` option. Note that you need to run `terraform init` first because of TFLint loads modules in the same way as Terraform.

You can use the `--ignore-module` option if you want to skip inspection for a particular module. Note that you need to pass module sources rather than module ids for backward compatibility.

Expand Down
2 changes: 1 addition & 1 deletion cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (cli *CLI) Run(args []string) int {

// Load Terraform's configurations
if !cli.testMode {
cli.loader, err = tflint.NewLoader()
cli.loader, err = tflint.NewLoader(cfg)
if err != nil {
cli.printError(fmt.Errorf("Failed to prepare loading: %s", err))
return ExitCodeError
Expand Down
3 changes: 3 additions & 0 deletions cmd/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Options struct {
IgnoreRule string `long:"ignore-rule" description:"Ignore rule names" value-name:"RULE1,RULE2..."`
Varfile string `long:"var-file" description:"Terraform variable file names" value-name:"FILE1,FILE2..."`
Variables []string `long:"var" description:"Set a Terraform variable" value-name:"'foo=bar'"`
Module bool `long:"module" description:"Inspect modules"`
Deep bool `long:"deep" description:"Enable deep check mode"`
AwsAccessKey string `long:"aws-access-key" description:"AWS access key used in deep check mode" value-name:"ACCESS_KEY"`
AwsSecretKey string `long:"aws-secret-key" description:"AWS secret key used in deep check mode" value-name:"SECRET_KEY"`
Expand Down Expand Up @@ -50,6 +51,7 @@ func (opts *Options) toConfig() *tflint.Config {
}

log.Printf("[DEBUG] CLI Options")
log.Printf("[DEBUG] Module: %t", opts.Module)
log.Printf("[DEBUG] DeepCheck: %t", opts.Deep)
log.Printf("[DEBUG] Force: %t", opts.Force)
log.Printf("[DEBUG] IgnoreModule: %#v", ignoreModule)
Expand All @@ -58,6 +60,7 @@ func (opts *Options) toConfig() *tflint.Config {
log.Printf("[DEBUG] Variables: %#v", opts.Variables)

return &tflint.Config{
Module: opts.Module,
DeepCheck: opts.Deep,
Force: opts.Force,
AwsCredentials: client.AwsCredentials{
Expand Down
23 changes: 23 additions & 0 deletions cmd/option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,26 @@ func Test_toConfig(t *testing.T) {
Command: "./tflint",
Expected: tflint.EmptyConfig(),
},
{
Name: "--module",
Command: "./tflint --module",
Expected: &tflint.Config{
Module: true,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{},
IgnoreModule: map[string]bool{},
IgnoreRule: map[string]bool{},
Varfile: []string{},
Variables: []string{},
Rules: map[string]*tflint.RuleConfig{},
},
},
{
Name: "--deep",
Command: "./tflint --deep",
Expected: &tflint.Config{
Module: false,
DeepCheck: true,
Force: false,
AwsCredentials: client.AwsCredentials{},
Expand All @@ -39,6 +55,7 @@ func Test_toConfig(t *testing.T) {
Name: "--force",
Command: "./tflint --force",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: true,
AwsCredentials: client.AwsCredentials{},
Expand All @@ -53,6 +70,7 @@ func Test_toConfig(t *testing.T) {
Name: "AWS static credentials",
Command: "./tflint --aws-access-key AWS_ACCESS_KEY_ID --aws-secret-key AWS_SECRET_ACCESS_KEY --aws-region us-east-1",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{
Expand All @@ -71,6 +89,7 @@ func Test_toConfig(t *testing.T) {
Name: "AWS shared credentials",
Command: "./tflint --aws-profile production --aws-region us-east-1",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{
Expand All @@ -88,6 +107,7 @@ func Test_toConfig(t *testing.T) {
Name: "--ignore-module",
Command: "./tflint --ignore-module module1,module2",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{},
Expand All @@ -102,6 +122,7 @@ func Test_toConfig(t *testing.T) {
Name: "--ignore-rule",
Command: "./tflint --ignore-rule rule1,rule2",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{},
Expand All @@ -116,6 +137,7 @@ func Test_toConfig(t *testing.T) {
Name: "--var-file",
Command: "./tflint --var-file example1.tfvars,example2.tfvars",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{},
Expand All @@ -130,6 +152,7 @@ func Test_toConfig(t *testing.T) {
Name: "--var",
Command: "./tflint --var foo=bar --var bar=baz",
Expected: &tflint.Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{},
Expand Down
13 changes: 13 additions & 0 deletions integration/without_module_init/module.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
variable "unknown" {}

variable "instance_type" {
default = "t1.2xlarge"
}

// terraform init did not run
module "instances" {
source = "./module"

unknown = "${var.unknown}"
instance_type = "${var.instance_type}"
}
11 changes: 11 additions & 0 deletions integration/without_module_init/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"detector": "aws_instance_invalid_type",
"type": "ERROR",
"message": "\"t1.2xlarge\" is invalid instance type.",
"line": 2,
"file": "template.tf",
"link": ""
}
]

3 changes: 3 additions & 0 deletions integration/without_module_init/template.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "aws_instance" "foo" {
instance_type = "t1.2xlarge"
}
7 changes: 6 additions & 1 deletion integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,14 @@ func TestIntegration(t *testing.T) {
},
{
Name: "module",
Command: "./tflint --format json",
Command: "./tflint --format json --module",
Dir: "module",
},
{
Name: "without_module_init",
Command: "./tflint --format json",
Dir: "without_module_init",
},
{
Name: "arguments",
Command: fmt.Sprintf("./tflint --format json %s", filepath.Join("dir", "template.tf")),
Expand Down
11 changes: 11 additions & 0 deletions tflint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var fallbackConfigFile = "~/.tflint.hcl"

type rawConfig struct {
Config *struct {
Module *bool `hcl:"module"`
DeepCheck *bool `hcl:"deep_check"`
Force *bool `hcl:"force"`
AwsCredentials *map[string]string `hcl:"aws_credentials"`
Expand All @@ -31,6 +32,7 @@ type rawConfig struct {

// Config describes the behavior of TFLint
type Config struct {
Module bool
DeepCheck bool
Force bool
AwsCredentials client.AwsCredentials
Expand All @@ -51,6 +53,7 @@ type RuleConfig struct {
// It is mainly used for testing
func EmptyConfig() *Config {
return &Config{
Module: false,
DeepCheck: false,
Force: false,
AwsCredentials: client.AwsCredentials{},
Expand Down Expand Up @@ -106,6 +109,9 @@ func LoadConfig(file string) (*Config, error) {
func (c *Config) Merge(other *Config) *Config {
ret := c.copy()

if other.Module {
ret.Module = true
}
if other.DeepCheck {
ret.DeepCheck = true
}
Expand Down Expand Up @@ -160,6 +166,7 @@ func (c *Config) copy() *Config {
}

return &Config{
Module: c.Module,
DeepCheck: c.DeepCheck,
Force: c.Force,
AwsCredentials: c.AwsCredentials,
Expand Down Expand Up @@ -191,6 +198,7 @@ func loadConfigFromFile(file string) (*Config, error) {

cfg := raw.toConfig()
log.Printf("[DEBUG] Config loaded")
log.Printf("[DEBUG] Module: %t", cfg.Module)
log.Printf("[DEBUG] DeepCheck: %t", cfg.DeepCheck)
log.Printf("[DEBUG] Force: %t", cfg.Force)
log.Printf("[DEBUG] IgnoreModule: %#v", cfg.IgnoreModule)
Expand Down Expand Up @@ -229,6 +237,9 @@ func (raw *rawConfig) toConfig() *Config {
rc := raw.Config

if rc != nil {
if rc.Module != nil {
ret.Module = *rc.Module
}
if rc.DeepCheck != nil {
ret.DeepCheck = *rc.DeepCheck
}
Expand Down
13 changes: 13 additions & 0 deletions tflint/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func Test_LoadConfig(t *testing.T) {
Name: "load file",
File: filepath.Join(currentDir, "test-fixtures", "config", "config.hcl"),
Expected: &Config{
Module: true,
DeepCheck: true,
Force: true,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -64,6 +65,7 @@ func Test_LoadConfig(t *testing.T) {
File: filepath.Join(currentDir, "test-fixtures", "config", "not_found.hcl"),
Fallback: filepath.Join(currentDir, "test-fixtures", "config", "fallback.hcl"),
Expected: &Config{
Module: false,
DeepCheck: true,
Force: true,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -162,6 +164,7 @@ func Test_LoadConfig_error(t *testing.T) {

func Test_Merge(t *testing.T) {
cfg := &Config{
Module: true,
DeepCheck: true,
Force: true,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -218,6 +221,7 @@ func Test_Merge(t *testing.T) {
{
Name: "override and merge",
Base: &Config{
Module: true,
DeepCheck: true,
Force: false,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -248,6 +252,7 @@ func Test_Merge(t *testing.T) {
},
},
Other: &Config{
Module: false,
DeepCheck: false,
Force: true,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -277,6 +282,7 @@ func Test_Merge(t *testing.T) {
},
},
Expected: &Config{
Module: true,
DeepCheck: true, // DeepCheck will not override
Force: true,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -325,6 +331,7 @@ func Test_Merge(t *testing.T) {

func Test_copy(t *testing.T) {
cfg := &Config{
Module: true,
DeepCheck: true,
Force: true,
AwsCredentials: client.AwsCredentials{
Expand Down Expand Up @@ -358,6 +365,12 @@ func Test_copy(t *testing.T) {
Name string
SideEffect func(*Config)
}{
{
Name: "Module",
SideEffect: func(c *Config) {
c.Module = false
},
},
{
Name: "DeepCheck",
SideEffect: func(c *Config) {
Expand Down
20 changes: 19 additions & 1 deletion tflint/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type AbstractLoader interface {
type Loader struct {
loader *configload.Loader
currentDir string
config *Config
moduleSourceVersions map[string][]*version.Version
moduleManifest map[string]*moduleManifest
}
Expand All @@ -52,7 +53,7 @@ type moduleManifestFile struct {
}

// NewLoader returns a loader with module manifests
func NewLoader() (*Loader, error) {
func NewLoader(cfg *Config) (*Loader, error) {
log.Print("[INFO] Initialize new loader")

loader, err := configload.NewLoader(&configload.Config{
Expand All @@ -65,6 +66,7 @@ func NewLoader() (*Loader, error) {

l := &Loader{
loader: loader,
config: cfg,
moduleSourceVersions: map[string][]*version.Version{},
moduleManifest: map[string]*moduleManifest{},
}
Expand All @@ -91,6 +93,16 @@ func (l *Loader) LoadConfig(dir string) (*configs.Config, error) {
return nil, diags
}

if !l.config.Module {
log.Print("[INFO] Module inspection is disabled. Building a root module without children...")
cfg, diags := configs.BuildConfig(rootMod, l.ignoreModuleWalker())
if diags.HasErrors() {
return nil, diags
}
return cfg, nil
}
log.Print("[INFO] Module inspection is enabled. Building a root module with children...")

log.Print("[DEBUG] Trying to load modules using the legacy module walker...")
cfg, diags := configs.BuildConfig(rootMod, l.moduleWalkerLegacy())
if !diags.HasErrors() {
Expand Down Expand Up @@ -326,6 +338,12 @@ func (l *Loader) moduleWalkerV0_12() configs.ModuleWalker {
})
}

func (l *Loader) ignoreModuleWalker() configs.ModuleWalker {
return configs.ModuleWalkerFunc(func(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) {
return nil, nil, nil
})
}

func (l *Loader) initializeModuleManifest() error {
file, err := ioutil.ReadFile(getTFModuleManifestPath())
if err != nil {
Expand Down
Loading

0 comments on commit b18d8e3

Please sign in to comment.