diff --git a/README.md b/README.md index 16c89a60c..4266bd58b 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ Application Options: --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 --aws-profile=PROFILE AWS shared credential profile name used in deep check mode + --aws-creds-file=FILE Aws shared credentials file used in deep checking --aws-region=REGION AWS region used in deep check mode --force Return zero exit status even if issues found -q, --quiet Do not output any message when no issues are found (default format only) diff --git a/client/aws.go b/client/aws.go index 3dd204649..86abb10f3 100644 --- a/client/aws.go +++ b/client/aws.go @@ -48,14 +48,18 @@ type AwsCredentials struct { AccessKey string SecretKey string Profile string + CredsFile string Region string } // NewAwsClient returns new AwsClient with configured session -func NewAwsClient(creds AwsCredentials) *AwsClient { +func NewAwsClient(creds AwsCredentials) (*AwsClient, error) { log.Print("[INFO] Initialize AWS Client") - s := newAwsSession(creds) + s, err := newAwsSession(creds) + if err != nil { + return nil, err + } return &AwsClient{ IAM: iam.New(s), @@ -65,11 +69,11 @@ func NewAwsClient(creds AwsCredentials) *AwsClient { ELB: elb.New(s), ELBV2: elbv2.New(s), ECS: ecs.New(s), - } + }, nil } // newAwsSession returns a session necessary for initialization of the AWS SDK -func newAwsSession(creds AwsCredentials) *session.Session { +func newAwsSession(creds AwsCredentials) (*session.Session, error) { s := session.New() if creds.Region != "" { @@ -79,14 +83,23 @@ func newAwsSession(creds AwsCredentials) *session.Session { }) } if creds.Profile != "" && creds.Region != "" { - log.Printf("[INFO] Set AWS shared credentials") - path, err := homedir.Expand("~/.aws/credentials") - if err != nil { - // Maybe this is bug - panic(err) + var credsFile string + var err error + if creds.CredsFile != "" { + credsFile, err = homedir.Expand(creds.CredsFile) + if err != nil { + return nil, err + } + } else { + credsFile, err = homedir.Expand("~/.aws/credentials") + if err != nil { + // Maybe this is bug + panic(err) + } } + log.Printf("[INFO] Set AWS shared credentials: %s", credsFile) s = session.New(&aws.Config{ - Credentials: credentials.NewSharedCredentials(path, creds.Profile), + Credentials: credentials.NewSharedCredentials(credsFile, creds.Profile), Region: aws.String(creds.Region), }) } @@ -98,5 +111,5 @@ func newAwsSession(creds AwsCredentials) *session.Session { }) } - return s + return s, nil } diff --git a/client/aws_test.go b/client/aws_test.go index ff5d136af..19c835b32 100644 --- a/client/aws_test.go +++ b/client/aws_test.go @@ -15,6 +15,7 @@ func Test_newAwsSession(t *testing.T) { Region *string } path, _ := homedir.Expand("~/.aws/credentials") + credPath, _ := homedir.Expand("~/.aws/creds") cases := []struct { Name string @@ -44,10 +45,25 @@ func Test_newAwsSession(t *testing.T) { Region: aws.String("us-east-1"), }, }, + { + Name: "shared credentials path", + Creds: AwsCredentials{ + Profile: "default", + CredsFile: "~/.aws/creds", + Region: "us-east-1", + }, + Expected: Result{ + Credentials: credentials.NewSharedCredentials(credPath, "default"), + Region: aws.String("us-east-1"), + }, + }, } for _, tc := range cases { - s := newAwsSession(tc.Creds) + s, err := newAwsSession(tc.Creds) + if err != nil { + t.Fatalf("Failed `%s` test: Unexpected error occurred: %s", tc.Name, err) + } if !reflect.DeepEqual(tc.Expected.Credentials, s.Config.Credentials) { t.Fatalf("Failed `%s` test: expected credentials are `%#v`, but get `%#v`", tc.Name, tc.Expected.Credentials, s.Config.Credentials) } diff --git a/cmd/cli.go b/cmd/cli.go index 3016d5d03..73a9514a8 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -121,7 +121,11 @@ func (cli *CLI) Run(args []string) int { variables = append(variables, cliVars) // Check configurations via Runner - runner := tflint.NewRunner(cfg, annotations, configs, variables...) + runner, err := tflint.NewRunner(cfg, annotations, configs, variables...) + if err != nil { + cli.printError(fmt.Errorf("Failed to initialize a runner: %s", err)) + return ExitCodeError + } runners, err := tflint.NewModuleRunners(runner) if err != nil { cli.printError(fmt.Errorf("Failed to prepare rule checking: %s", err)) diff --git a/cmd/option.go b/cmd/option.go index 3c95ea7e3..660f10c63 100644 --- a/cmd/option.go +++ b/cmd/option.go @@ -22,6 +22,7 @@ type Options struct { 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"` AwsProfile string `long:"aws-profile" description:"AWS shared credential profile name used in deep check mode" value-name:"PROFILE"` + AwsCredsFile string `long:"aws-creds-file" description:"Aws shared credentials file used in deep checking" value-name:"FILE"` AwsRegion string `long:"aws-region" description:"AWS region used in deep check mode" value-name:"REGION"` Force bool `long:"force" description:"Return zero exit status even if issues found"` Quiet bool `short:"q" long:"quiet" description:"Do not output any message when no issues are found (default format only)"` @@ -67,6 +68,7 @@ func (opts *Options) toConfig() *tflint.Config { AccessKey: opts.AwsAccessKey, SecretKey: opts.AwsSecretKey, Profile: opts.AwsProfile, + CredsFile: opts.AwsCredsFile, Region: opts.AwsRegion, }, IgnoreModule: ignoreModule, diff --git a/cmd/option_test.go b/cmd/option_test.go index 78467c6ff..1ecb1c7b1 100644 --- a/cmd/option_test.go +++ b/cmd/option_test.go @@ -103,6 +103,25 @@ func Test_toConfig(t *testing.T) { Rules: map[string]*tflint.RuleConfig{}, }, }, + { + Name: "AWS shared credentials in another file", + Command: "./tflint --aws-creds-file ~/.aws/myapp --aws-profile production --aws-region us-east-1", + Expected: &tflint.Config{ + Module: false, + DeepCheck: false, + Force: false, + AwsCredentials: client.AwsCredentials{ + CredsFile: "~/.aws/myapp", + Profile: "production", + Region: "us-east-1", + }, + IgnoreModule: map[string]bool{}, + IgnoreRule: map[string]bool{}, + Varfile: []string{}, + Variables: []string{}, + Rules: map[string]*tflint.RuleConfig{}, + }, + }, { Name: "--ignore-module", Command: "./tflint --ignore-module module1,module2", diff --git a/docs/guides/config.md b/docs/guides/config.md index 8c00f41fb..636702333 100644 --- a/docs/guides/config.md +++ b/docs/guides/config.md @@ -63,7 +63,7 @@ Return zero exit status even if issues found. TFLint returns non-zero exit statu ## `aws_credentials` -CLI flag: `--aws-access-key`, `--aws-secret-key`, `--aws-profile` and `--aws-region` +CLI flag: `--aws-access-key`, `--aws-secret-key`, `--aws-profile`, `--aws-creds-file` and `--aws-region` Configure AWS service crendetials. See [Credentials](credentials.md). diff --git a/docs/guides/credentials.md b/docs/guides/credentials.md index d1adbc562..4e33ede5f 100644 --- a/docs/guides/credentials.md +++ b/docs/guides/credentials.md @@ -29,17 +29,18 @@ config { ## Shared Credentials -If you have [shared credentials](https://aws.amazon.com/jp/blogs/security/a-new-and-standardized-way-to-manage-credentials-in-the-aws-sdks/), you can pass the profile name. However, only `~/.aws/credentials` is supported as a credential location. +If you have [shared credentials](https://aws.amazon.com/jp/blogs/security/a-new-and-standardized-way-to-manage-credentials-in-the-aws-sdks/), you can pass a profile name and credentials file location. If omitted, these will be `default` and `~/.aws/credentials`. ``` -$ tflint --aws-profile AWS_PROFILE --aws-region us-east-1 +$ tflint --aws-profile AWS_PROFILE --aws-region us-east-1 --aws-creds-file ~/.aws/myapp ``` ```hcl config { aws_credentials = { - profile = "AWS_PROFILE" - region = "us-east-1" + profile = "AWS_PROFILE" + region = "us-east-1" + shared_credentials_file = "~/.aws/myapp" } } ``` diff --git a/tflint/config.go b/tflint/config.go index ed574a4e2..3eb2503e2 100644 --- a/tflint/config.go +++ b/tflint/config.go @@ -128,6 +128,9 @@ func (c *Config) Merge(other *Config) *Config { if other.AwsCredentials.Profile != "" { ret.AwsCredentials.Profile = other.AwsCredentials.Profile } + if other.AwsCredentials.CredsFile != "" { + ret.AwsCredentials.CredsFile = other.AwsCredentials.CredsFile + } if other.AwsCredentials.Region != "" { ret.AwsCredentials.Region = other.AwsCredentials.Region } @@ -251,6 +254,7 @@ func (raw *rawConfig) toConfig() *Config { ret.AwsCredentials.AccessKey = credentials["access_key"] ret.AwsCredentials.SecretKey = credentials["secret_key"] ret.AwsCredentials.Profile = credentials["profile"] + ret.AwsCredentials.CredsFile = credentials["shared_credentials_file"] ret.AwsCredentials.Region = credentials["region"] } if rc.IgnoreModule != nil { diff --git a/tflint/config_test.go b/tflint/config_test.go index ec07a1194..36e4db569 100644 --- a/tflint/config_test.go +++ b/tflint/config_test.go @@ -33,6 +33,8 @@ func Test_LoadConfig(t *testing.T) { AccessKey: "AWS_ACCESS_KEY", SecretKey: "AWS_SECRET_KEY", Region: "us-east-1", + Profile: "production", + CredsFile: "~/.aws/myapp", }, IgnoreRule: map[string]bool{ "aws_instance_invalid_type": true, @@ -259,6 +261,7 @@ func Test_Merge(t *testing.T) { AccessKey: "ACCESS_KEY", SecretKey: "SECRET_KEY", Region: "ap-northeast-1", + CredsFile: "~/.aws/myapp", }, IgnoreModule: map[string]bool{ "github.com/wata727/example-2": true, @@ -290,6 +293,7 @@ func Test_Merge(t *testing.T) { SecretKey: "SECRET_KEY", Profile: "production", Region: "ap-northeast-1", + CredsFile: "~/.aws/myapp", }, IgnoreModule: map[string]bool{ "github.com/wata727/example-1": true, diff --git a/tflint/runner.go b/tflint/runner.go index 902f21900..6e755b90e 100644 --- a/tflint/runner.go +++ b/tflint/runner.go @@ -43,17 +43,22 @@ type Rule interface { // NewRunner returns new TFLint runner // It prepares built-in context (workpace metadata, variables) from // received `configs.Config` and `terraform.InputValues` -func NewRunner(c *Config, ants map[string]Annotations, cfg *configs.Config, variables ...terraform.InputValues) *Runner { +func NewRunner(c *Config, ants map[string]Annotations, cfg *configs.Config, variables ...terraform.InputValues) (*Runner, error) { path := "root" if !cfg.Path.IsRoot() { path = cfg.Path.String() } log.Printf("[INFO] Initialize new runner for %s", path) + awsClient, err := client.NewAwsClient(c.AwsCredentials) + if err != nil { + return nil, err + } + return &Runner{ TFConfig: cfg, Issues: []*issue.Issue{}, - AwsClient: client.NewAwsClient(c.AwsCredentials), + AwsClient: awsClient, ctx: terraform.BuiltinEvalContext{ Evaluator: &terraform.Evaluator{ @@ -67,7 +72,7 @@ func NewRunner(c *Config, ants map[string]Annotations, cfg *configs.Config, vari }, annotations: ants, config: c, - } + }, nil } // NewModuleRunners returns new TFLint runners for child modules @@ -139,7 +144,10 @@ func NewModuleRunners(parent *Runner) ([]*Runner, error) { } // Annotation does not work with children modules - runner := NewRunner(parent.config, map[string]Annotations{}, cfg) + runner, err := NewRunner(parent.config, map[string]Annotations{}, cfg) + if err != nil { + return runners, err + } runners = append(runners, runner) moudleRunners, err := NewModuleRunners(runner) if err != nil { diff --git a/tflint/runner_test.go b/tflint/runner_test.go index 13519b0f1..a512ae8b0 100644 --- a/tflint/runner_test.go +++ b/tflint/runner_test.go @@ -167,7 +167,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } var ret string err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -234,7 +237,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } var ret int err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -285,7 +291,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } ret := []string{} err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -336,7 +345,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } ret := []int{} err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -390,7 +402,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } ret := map[string]string{} err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -444,7 +459,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } ret := map[string]int{} err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -556,7 +574,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } expectedText := fmt.Sprintf(tc.ErrorText, filepath.Join(dir, "resource.tf")) @@ -667,7 +688,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } expectedText := fmt.Sprintf(tc.ErrorText, filepath.Join(dir, "resource.tf")) @@ -933,7 +957,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, tc.InputValues...) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, tc.InputValues...) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } var ret string err = runner.EvaluateExpr(attribute.Expr, &ret) @@ -975,7 +1002,7 @@ func Test_NewModuleRunners_noModules(t *testing.T) { t.Fatalf("Unexpected error occurred: %s", err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) runners, err := NewModuleRunners(runner) if err != nil { t.Fatalf("Unexpected error occurred: %s", err) @@ -1007,7 +1034,7 @@ func Test_NewModuleRunners_nestedModules(t *testing.T) { t.Fatalf("Unexpected error occurred: %s", err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) runners, err := NewModuleRunners(runner) if err != nil { t.Fatalf("Unexpected error occurred: %s", err) @@ -1138,7 +1165,7 @@ func Test_NewModuleRunners_ignoreModules(t *testing.T) { conf := EmptyConfig() conf.IgnoreModule["./module"] = true - runner := NewRunner(conf, map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(conf, map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) runners, err := NewModuleRunners(runner) if err != nil { t.Fatalf("Unexpected error occurred: %s", err) @@ -1170,7 +1197,11 @@ func Test_NewModuleRunners_withInvalidExpression(t *testing.T) { t.Fatalf("Unexpected error occurred: %s", err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + _, err = NewModuleRunners(runner) errText := "Failed to eval an expression in module.tf:4; Invalid \"terraform\" attribute: The terraform.env attribute was deprecated in v0.10 and removed in v0.12. The \"state environment\" concept was rename to \"workspace\" in v0.12, and so the workspace name can now be accessed using the terraform.workspace attribute." @@ -1216,7 +1247,11 @@ func Test_NewModuleRunners_withNotAllowedAttributes(t *testing.T) { t.Fatalf("Unexpected error occurred: %s", err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + _, err = NewModuleRunners(runner) errText := "Attribute of module not allowed was found in module.tf:1; module.tf:4,3-10: Unexpected \"invalid\" block; Blocks are not allowed here." @@ -1278,7 +1313,11 @@ resource "aws_route" "r" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + resources := runner.LookupResourcesByType("aws_instance") if len(resources) != 1 { @@ -1290,7 +1329,11 @@ resource "aws_route" "r" { } func Test_LookupIssues(t *testing.T) { - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, configs.NewEmptyConfig(), map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, configs.NewEmptyConfig(), map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + runner.Issues = issue.Issues{ { Detector: "test rule", @@ -1379,7 +1422,10 @@ resource "aws_instance" "test" { if err != nil { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } err = runner.WalkResourceAttributes("aws_instance", "instance_type", func(attribute *hcl.Attribute) error { return fmt.Errorf("Walk %s", attribute.Name) @@ -1480,7 +1526,10 @@ resource "aws_instance" "test" { if err != nil { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } err = runner.WalkResourceBlocks("aws_instance", "instance_type", func(block *hcl.Block) error { return fmt.Errorf("Walk %s", block.Type) @@ -1537,7 +1586,10 @@ func Test_EnsureNoError(t *testing.T) { defer os.RemoveAll(dir) for _, tc := range cases { - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, configs.NewEmptyConfig(), map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, configs.NewEmptyConfig(), map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } err = runner.EnsureNoError(tc.Error, func() error { return errors.New("function called") @@ -1647,7 +1699,10 @@ resource "null_resource" "test" { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } ret := runner.IsNullExpr(attribute.Expr) if tc.Expected != ret { @@ -1726,7 +1781,10 @@ resource "null_resource" "test" { if err != nil { t.Fatal(err) } - runner := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), map[string]Annotations{}, cfg, map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } vals := []string{} lines := []int{} @@ -1822,7 +1880,10 @@ func Test_EmitIssue(t *testing.T) { defer os.RemoveAll(dir) for _, tc := range cases { - runner := NewRunner(EmptyConfig(), tc.Annotations, configs.NewEmptyConfig(), map[string]*terraform.InputValue{}) + runner, err := NewRunner(EmptyConfig(), tc.Annotations, configs.NewEmptyConfig(), map[string]*terraform.InputValue{}) + if err != nil { + t.Fatalf("Failed %s test: Unexpected error: %s", tc.Name, err) + } runner.EmitIssue(tc.Rule, tc.Message, tc.Location) diff --git a/tflint/test-fixtures/config/config.hcl b/tflint/test-fixtures/config/config.hcl index 477ef692b..11a7b3e32 100644 --- a/tflint/test-fixtures/config/config.hcl +++ b/tflint/test-fixtures/config/config.hcl @@ -4,9 +4,11 @@ config { force = true aws_credentials = { - access_key = "AWS_ACCESS_KEY" - secret_key = "AWS_SECRET_KEY" - region = "us-east-1" + access_key = "AWS_ACCESS_KEY" + secret_key = "AWS_SECRET_KEY" + region = "us-east-1" + profile = "production" + shared_credentials_file = "~/.aws/myapp" } ignore_rule = {