command/validate: Add flag to check that all variables are specified (#13872)

* command/validate: Add flag to check that all variables are specified

* Rename config-only to check-variables
pull/15479/head
Radek Simko 9 years ago committed by GitHub
parent 86a73701e9
commit 14614a5423

@ -0,0 +1,10 @@
resource "test_instance" "foo" {
ami = "bar"
network_interface {
device_index = 0
description = "Main network interface ${var.name}"
}
}
variable "name" {}

@ -1,12 +1,12 @@
package command
import (
"flag"
"fmt"
"path/filepath"
"strings"
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/terraform"
)
// ValidateCommand is a Command implementation that validates the terraform files
@ -17,15 +17,21 @@ type ValidateCommand struct {
const defaultPath = "."
func (c *ValidateCommand) Run(args []string) int {
args = c.Meta.process(args, false)
var dirPath string
args = c.Meta.process(args, true)
var checkVars bool
cmdFlags := flag.NewFlagSet("validate", flag.ContinueOnError)
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
cmdFlags := c.Meta.flagSet("validate")
cmdFlags.BoolVar(&checkVars, "check-variables", true, "check-variables")
cmdFlags.Usage = func() {
c.Ui.Error(c.Help())
}
if err := cmdFlags.Parse(args); err != nil {
return 1
}
args = cmdFlags.Args()
var dirPath string
if len(args) == 1 {
dirPath = args[0]
} else {
@ -37,7 +43,7 @@ func (c *ValidateCommand) Run(args []string) int {
"Unable to locate directory %v\n", err.Error()))
}
rtnCode := c.validate(dir)
rtnCode := c.validate(dir, checkVars)
return rtnCode
}
@ -48,24 +54,38 @@ func (c *ValidateCommand) Synopsis() string {
func (c *ValidateCommand) Help() string {
helpText := `
Usage: terraform validate [options] [path]
Usage: terraform validate [options] [dir]
Validate the terraform files in a directory. Validation includes a
basic check of syntax as well as checking that all variables declared
in the configuration are specified in one of the possible ways:
Reads the Terraform files in the given path (directory) and
validates their syntax and basic semantics.
-var foo=...
-var-file=foo.vars
TF_VAR_foo environment variable
terraform.tfvars
default value
This is not a full validation that is normally done with
a plan or apply operation, but can be used to verify the basic
syntax and usage of Terraform configurations is correct.
If dir is not specified, then the current directory will be used.
Options:
-no-color If specified, output won't contain any color.
-check-variables=true If set to true (default), the command will check
whether all required variables have been specified.
-no-color If specified, output won't contain any color.
-var 'foo=bar' Set a variable in the Terraform configuration. This
flag can be set multiple times.
-var-file=foo Set variables in the Terraform configuration from
a file. If "terraform.tfvars" is present, it will be
automatically loaded if this flag is not specified.
`
return strings.TrimSpace(helpText)
}
func (c *ValidateCommand) validate(dir string) int {
func (c *ValidateCommand) validate(dir string, checkVars bool) int {
cfg, err := config.LoadDir(dir)
if err != nil {
c.Ui.Error(fmt.Sprintf(
@ -78,5 +98,27 @@ func (c *ValidateCommand) validate(dir string) int {
"Error validating: %v\n", err.Error()))
return 1
}
if checkVars {
mod, err := c.Module(dir)
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to load root config module: %s", err))
return 1
}
opts := c.contextOpts()
opts.Module = mod
tfCtx, err := terraform.NewContext(opts)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error: %v\n", err.Error()))
return 1
}
if !validateContext(tfCtx, c.Ui) {
return 1
}
}
return 0
}

@ -7,21 +7,21 @@ import (
"github.com/mitchellh/cli"
)
func setupTest(fixturepath string) (*cli.MockUi, int) {
func setupTest(fixturepath string, args ...string) (*cli.MockUi, int) {
ui := new(cli.MockUi)
c := &ValidateCommand{
Meta: Meta{
Ui: ui,
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
testFixturePath(fixturepath),
}
args = append(args, testFixturePath(fixturepath))
code := c.Run(args)
return ui, code
}
func TestValidateCommand(t *testing.T) {
if ui, code := setupTest("validate-valid"); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
@ -122,3 +122,21 @@ func TestWronglyUsedInterpolationShouldFail(t *testing.T) {
t.Fatalf("Should have failed: %d\n\n'%s'", code, ui.ErrorWriter.String())
}
}
func TestMissingDefinedVar(t *testing.T) {
ui, code := setupTest("validate-invalid/missing_defined_var")
if code != 1 {
t.Fatalf("Should have failed: %d\n\n%s", code, ui.ErrorWriter.String())
}
if !strings.Contains(ui.ErrorWriter.String(), "Required variable not set:") {
t.Fatalf("Should have failed: %d\n\n'%s'", code, ui.ErrorWriter.String())
}
}
func TestMissingDefinedVarConfigOnly(t *testing.T) {
ui, code := setupTest("validate-invalid/missing_defined_var", "-check-variables=false")
if code != 0 {
t.Fatalf("Should have passed: %d\n\n%s", code, ui.ErrorWriter.String())
}
}

@ -24,10 +24,31 @@ The following can be reported:
* invalid `module` name
* interpolation used in places where it's unsupported
(e.g. `variable`, `depends_on`, `module.source`, `provider`)
* missing value for a variable (none of `-var foo=...` flag,
`-var-file=foo.vars` flag, `TF_VAR_foo` environment variable,
`terraform.tfvars`, or default value in the configuration)
## Usage
Usage: `terraform validate [dir]`
Usage: `terraform validate [options] [dir]`
By default, `validate` requires no flags and looks in the current directory
for the configurations.
for the configurations.
The command-line flags are all optional. The available flags are:
* `-check-variables=true` - If set to true (default), the command will check
whether all required variables have been specified.
* `-no-color` - Disables output with coloring.
* `-var 'foo=bar'` - Set a variable in the Terraform configuration. This flag
can be set multiple times. Variable values are interpreted as
[HCL](/docs/configuration/syntax.html#HCL), so list and map values can be
specified via this flag.
* `-var-file=foo` - Set variables in the Terraform configuration from
a [variable file](/docs/configuration/variables.html#variable-files). If
"terraform.tfvars" is present, it will be automatically loaded first. Any
files specified by `-var-file` override any values in a "terraform.tfvars".
This flag can be used multiple times.

Loading…
Cancel
Save