-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added command to locally validate terraform configuration (#449)
<!-- Describe in detail the changes you are proposing, and the rationale. --> <!-- Link all GitHub issues fixed by this PR, and add references to prior related PRs. --> Fixes # ### NEW FEATURES | UPGRADE NOTES | ENHANCEMENTS | BUG FIXES | EXPERIMENTS <!-- Write a short description of your changes. Examples: - Adds a command to run a validation on the generated configuration. This is useful to run locally or in the pipeline --> -
- Loading branch information
Showing
12 changed files
with
286 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
kind: Added | ||
body: Added command to validate terraform configurations | ||
time: 2024-09-13T11:30:45.83129735+02:00 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
## mach-composer validate | ||
|
||
Validate the generated terraform configuration. | ||
|
||
### Synopsis | ||
|
||
This command validates the generated terraform configuration. It will check the provided configuration file for any errors, and will run `terraform validate` on the generated configuration. This will check for any syntax errors in the generated configuration without accessing the actual infrastructure. | ||
|
||
By default, the generated configuration is stored in the `validations` directory in the current working directory. This can be changed by providing the `--validation-path` flag. | ||
|
||
See [the terraform validation docs](https://www.terraform.io/docs/commands/validate.html) for more information on `terraform validate`. | ||
|
||
``` | ||
mach-composer validate [flags] | ||
``` | ||
|
||
### Options | ||
|
||
``` | ||
-f, --file string YAML file to parse. (default "main.yml") | ||
-h, --help help for validate | ||
--ignore-version Skip MACH composer version check | ||
--output-path string Outputs path to store the generated files. (default "deployments") | ||
-s, --site string Site to parse. If not set parse all sites. | ||
--validation-path string Directory path to store files required for configuration validation. (default "validations") | ||
--var-file string Use a variable file to parse the configuration with. | ||
-w, --workers int The number of workers to use (default 1) | ||
``` | ||
|
||
### Options inherited from parent commands | ||
|
||
``` | ||
-q, --quiet Quiet output. This is equal to setting log levels to error and higher | ||
-v, --verbose Verbose output. This is equal to setting log levels to debug and higher | ||
``` | ||
|
||
### SEE ALSO | ||
|
||
* [mach-composer](mach-composer.md) - MACH composer is an orchestration tool for modern MACH ecosystems | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
**/deployments | ||
**/validations | ||
**/states |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
mach_composer: | ||
version: 1 | ||
deployment: | ||
type: "site-component" | ||
plugins: | ||
aws: | ||
source: mach-composer/aws | ||
version: 0.1.0 | ||
|
||
global: | ||
cloud: "aws" | ||
environment: test | ||
terraform_config: | ||
remote_state: | ||
plugin: local | ||
path: ./states | ||
|
||
sites: | ||
- identifier: test-1 | ||
aws: | ||
account_id: "12345" | ||
region: eu-west-1 | ||
components: | ||
- name: component-1 | ||
|
||
components: | ||
- name: component-1 | ||
source: ./testdata/modules/application | ||
version: "test" | ||
branch: main | ||
integrations: | ||
- aws | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
mach_composer: | ||
version: 1 | ||
plugins: | ||
aws: | ||
source: mach-composer/aws | ||
version: 0.1.0 | ||
|
||
global: | ||
cloud: "" | ||
environment: test | ||
terraform_config: | ||
remote_state: | ||
plugin: local | ||
path: ./states | ||
|
||
sites: | ||
- identifier: test-1 | ||
aws: | ||
account_id: "12345" | ||
region: eu-west-1 | ||
components: | ||
- name: component-1 | ||
variables: | ||
parent_names: [ ] | ||
|
||
components: | ||
- name: component-1 | ||
source: ./testdata/modules/application | ||
version: "test" | ||
branch: main | ||
integrations: | ||
- aws | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/mach-composer/mach-composer-cli/internal/batcher" | ||
"github.com/mach-composer/mach-composer-cli/internal/cli" | ||
"github.com/mach-composer/mach-composer-cli/internal/graph" | ||
"github.com/mach-composer/mach-composer-cli/internal/hash" | ||
"github.com/spf13/cobra" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
|
||
"github.com/mach-composer/mach-composer-cli/internal/generator" | ||
"github.com/mach-composer/mach-composer-cli/internal/runner" | ||
) | ||
|
||
var validateFlags struct { | ||
validationPath string | ||
} | ||
|
||
var validateCmd = &cobra.Command{ | ||
Use: "validate", | ||
Short: "Validate the generated terraform configuration.", | ||
Long: "This command validates the generated terraform configuration. It will check the provided configuration file " + | ||
"for any errors, and will run `terraform validate` on the generated configuration. This will check for any " + | ||
"syntax errors in the generated configuration without accessing the actual infrastructure.\n\n" + | ||
"By default, the generated configuration is stored in the `validations` directory in the current " + | ||
"working directory. This can be changed by providing the `--validation-path` flag.\n\n" + | ||
"See [the terraform validation docs](https://www.terraform.io/docs/commands/validate.html) for more " + | ||
"information on `terraform validate`.", | ||
PreRun: func(cmd *cobra.Command, args []string) { | ||
preprocessCommonFlags(cmd) | ||
}, | ||
|
||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return validateFunc(cmd, args) | ||
}, | ||
} | ||
|
||
func init() { | ||
registerCommonFlags(validateCmd) | ||
validateCmd.Flags().StringVarP(&validateFlags.validationPath, "validation-path", "", "validations", | ||
"Directory path to store files required for configuration validation.") | ||
|
||
if path.IsAbs(validateFlags.validationPath) == false { | ||
var err error | ||
value, err := os.Getwd() | ||
if err != nil { | ||
cli.PrintExitError("failed to get current working directory") | ||
} | ||
validateFlags.validationPath = filepath.Join(value, validateFlags.validationPath) | ||
} | ||
} | ||
|
||
func validateFunc(cmd *cobra.Command, _ []string) error { | ||
cfg := loadConfig(cmd, true) | ||
defer cfg.Close() | ||
ctx := cmd.Context() | ||
|
||
dg, err := graph.ToDeploymentGraph(cfg, validateFlags.validationPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = generator.Write(ctx, cfg, dg, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
r := runner.NewGraphRunner( | ||
batcher.NaiveBatchFunc(), | ||
hash.Factory(cfg), | ||
commonFlags.workers, | ||
) | ||
|
||
return r.TerraformValidate(ctx, dg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/suite" | ||
"os" | ||
"os/exec" | ||
"path" | ||
"testing" | ||
) | ||
|
||
type ValidateTestSuite struct { | ||
suite.Suite | ||
tempDir string | ||
} | ||
|
||
func TestValidateTestSuite(t *testing.T) { | ||
suite.Run(t, new(ValidateTestSuite)) | ||
} | ||
|
||
func (s *ValidateTestSuite) SetupSuite() { | ||
_, err := exec.LookPath("terraform") | ||
if err != nil { | ||
s.T().Fatal("terraform command not found") | ||
} | ||
|
||
tmpDir, _ := os.MkdirTemp("mach-composer", "test") | ||
_ = os.Setenv("TF_PLUGIN_CACHE_DIR", tmpDir) | ||
_ = os.Setenv("TF_PLUGIN_CACHE_MAY_BREAK_DEPENDENCY_LOCK_FILE", "1") | ||
|
||
s.tempDir = tmpDir | ||
} | ||
|
||
func (s *ValidateTestSuite) TearDownSuite() { | ||
_ = os.RemoveAll(s.tempDir) | ||
} | ||
|
||
func (s *ValidateTestSuite) TestValidateInvalid() { | ||
pwd, _ := os.Getwd() | ||
workdir := path.Join(pwd, "testdata/cases/validate/invalid") | ||
|
||
cmd := RootCmd | ||
cmd.SetArgs([]string{ | ||
"validate", | ||
"--file", path.Join(workdir, "main.yaml"), | ||
"--validation-path", path.Join(workdir, "validations"), | ||
}) | ||
err := cmd.Execute() | ||
assert.Error(s.T(), err) | ||
} | ||
|
||
func (s *ValidateTestSuite) TestValidateValid() { | ||
pwd, _ := os.Getwd() | ||
workdir := path.Join(pwd, "testdata/cases/validate/valid") | ||
|
||
cmd := RootCmd | ||
cmd.SetArgs([]string{ | ||
"validate", | ||
"--file", path.Join(workdir, "main.yaml"), | ||
"--validation-path", path.Join(workdir, "validations"), | ||
}) | ||
err := cmd.Execute() | ||
assert.NoError(s.T(), err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package terraform | ||
|
||
import ( | ||
"context" | ||
"github.com/mach-composer/mach-composer-cli/internal/utils" | ||
) | ||
|
||
func Validate(ctx context.Context, path string) (string, error) { | ||
cmd := []string{"validate"} | ||
|
||
return utils.RunTerraform(ctx, path, false, cmd...) | ||
} |