mirror of https://github.com/databricks/cli.git
Improved error message when 'bricks bundle run' is executed before 'bricks bundle deploy' (#378)
## Changes Improved error message when 'bricks bundle run' is executed before 'bricks bundle deploy' The error happens when we attempt to load terraform state when it does not exist. The best way to check if terraform state actually exists is to call `terraform show -json` and that's what already happens here https://github.com/databricks/bricks/compare/main...error-before-deploy#diff-8c50f8c04e568397bc865b7e02d1f4ec5b18379d8d32daddfeb041035d804f5fL28 Absence of `state.Values` indicates that there is no state and likely bundle was just never deployed. ## Tests Ran `bricks bundle run test_job` on a new non-deployed bundle. **Output:** `Error: terraform show: No state. Did you forget to run 'bricks bundle deploy'?` Running `bricks bundle deploy && bricks bundle run test_job` succeeds. --------- Co-authored-by: Pieter Noordhuis <pieter.noordhuis@databricks.com>
This commit is contained in:
parent
1916bc9d68
commit
473d2bf503
|
@ -154,14 +154,6 @@ func BundleToTerraform(config *config.Root) *schema.Root {
|
|||
}
|
||||
|
||||
func TerraformToBundle(state *tfjson.State, config *config.Root) error {
|
||||
if state.Values == nil {
|
||||
return fmt.Errorf("state.Values not set")
|
||||
}
|
||||
|
||||
if state.Values.RootModule == nil {
|
||||
return fmt.Errorf("state.Values.RootModule not set")
|
||||
}
|
||||
|
||||
for _, resource := range state.Values.RootModule.Resources {
|
||||
// Limit to resources.
|
||||
if resource.Mode != tfjson.ManagedResourceMode {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/databricks/bricks/bundle"
|
||||
"github.com/hashicorp/terraform-exec/tfexec"
|
||||
tfjson "github.com/hashicorp/terraform-json"
|
||||
)
|
||||
|
||||
type load struct{}
|
||||
|
@ -30,6 +31,11 @@ func (l *load) Apply(ctx context.Context, b *bundle.Bundle) ([]bundle.Mutator, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err = ValidateState(state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Merge state into configuration.
|
||||
err = TerraformToBundle(state, &b.Config)
|
||||
if err != nil {
|
||||
|
@ -39,6 +45,18 @@ func (l *load) Apply(ctx context.Context, b *bundle.Bundle) ([]bundle.Mutator, e
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func ValidateState(state *tfjson.State) error {
|
||||
if state.Values == nil {
|
||||
return fmt.Errorf("no deployment state. Did you forget to run 'bricks bundle deploy'?")
|
||||
}
|
||||
|
||||
if state.Values.RootModule == nil {
|
||||
return fmt.Errorf("malformed terraform state: RootModule not set")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Load() bundle.Mutator {
|
||||
return &load{}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package terraform
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/databricks/bricks/bundle"
|
||||
"github.com/databricks/bricks/bundle/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLoadWithNoState(t *testing.T) {
|
||||
_, err := exec.LookPath("terraform")
|
||||
if err != nil {
|
||||
t.Skipf("cannot find terraform binary: %s", err)
|
||||
}
|
||||
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Path: t.TempDir(),
|
||||
Bundle: config.Bundle{
|
||||
Environment: "whatever",
|
||||
Terraform: &config.Terraform{
|
||||
ExecPath: "terraform",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
t.Setenv("DATABRICKS_HOST", "https://x")
|
||||
t.Setenv("DATABRICKS_TOKEN", "foobar")
|
||||
b.WorkspaceClient()
|
||||
|
||||
err = bundle.Apply(context.Background(), b, []bundle.Mutator{
|
||||
Initialize(),
|
||||
Load(),
|
||||
})
|
||||
|
||||
require.ErrorContains(t, err, "Did you forget to run 'bricks bundle deploy'")
|
||||
}
|
Loading…
Reference in New Issue