Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bundle:
name: test-bundle-$UNIQUE_NAME
11 changes: 11 additions & 0 deletions acceptance/bundle/config-remote-sync/empty_deploy/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default/files...
Deploying resources...
Deployment complete!

>>> [CLI] bundle destroy --auto-approve
All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle-[UNIQUE_NAME]/default

Deleting files...
Destroy complete!
10 changes: 10 additions & 0 deletions acceptance/bundle/config-remote-sync/empty_deploy/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

envsubst < databricks.yml.tmpl > databricks.yml

cleanup() {
trace $CLI bundle destroy --auto-approve
}
trap cleanup EXIT

trace $CLI bundle deploy
10 changes: 10 additions & 0 deletions acceptance/bundle/config-remote-sync/empty_deploy/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Cloud = true

RecordRequests = false
Ignore = [".databricks", "databricks.yml"]

[Env]
DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC = "true"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a test with empty bundle already somewhere (if not, we should have it). We can then use EnvMatrix to run it both with DATABRICKS_BUNDLE_ENABLE_EXPERIMENTAL_YAML_SYNC and without.

Perhaps there are more tests where we need to test this variant?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added matrix to the acceptance/bundle/deploy/empty-bundle/test.toml


[EnvMatrix]
DATABRICKS_BUNDLE_ENGINE = ["terraform"]
42 changes: 26 additions & 16 deletions bundle/statemgmt/upload_state_for_yaml_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,17 @@ func (m *uploadStateForYamlSync) Apply(ctx context.Context, b *bundle.Bundle) di

_, snapshotPath := b.StateFilenameConfigSnapshot(ctx)

diags := m.convertState(ctx, b, snapshotPath)
created, diags := m.convertState(ctx, b, snapshotPath)
if diags.HasError() {
return diags
return diag.Warningf("Failed to create config snapshot: %v", diags.Error())
}
if !created {
return nil
}

err := uploadState(ctx, b)
if err != nil {
return diags.Extend(diag.Warningf("Failed to upload config snapshot to workspace: %v", err))
return diag.Warningf("Failed to upload config snapshot to workspace: %v", err)
}

log.Infof(ctx, "Config snapshot created at %s", snapshotPath)
Expand Down Expand Up @@ -92,10 +95,22 @@ func uploadState(ctx context.Context, b *bundle.Bundle) error {
return nil
}

func (m *uploadStateForYamlSync) convertState(ctx context.Context, b *bundle.Bundle, snapshotPath string) (diags diag.Diagnostics) {
func (m *uploadStateForYamlSync) convertState(ctx context.Context, b *bundle.Bundle, snapshotPath string) (bool, diag.Diagnostics) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated question, since it was added previously, but do you need to collect diagnostics? Why not just logs errors and warnings directly? (or logdiag.LogError/logdiag.LogError if you need diagnostics formatting).

terraformResources, err := terraform.ParseResourcesState(ctx, b)
if err != nil {
return diag.FromErr(err)
return false, diag.FromErr(fmt.Errorf("failed to parse terraform state for config snapshot: %w", err))
}

// ParseResourcesState returns nil when the terraform state file doesn't exist
// (e.g. first deploy with no resources).
if terraformResources == nil {
return false, nil
}

_, localTerraformPath := b.StateFilenameTerraform(ctx)
data, err := os.ReadFile(localTerraformPath)
if err != nil {
return false, diag.FromErr(fmt.Errorf("failed to read terraform state for config snapshot: %w", err))
}

state := make(map[string]dstate.ResourceEntry)
Expand All @@ -111,18 +126,12 @@ func (m *uploadStateForYamlSync) convertState(ctx context.Context, b *bundle.Bun
}
}

_, localTerraformPath := b.StateFilenameTerraform(ctx)
data, err := os.ReadFile(localTerraformPath)
if err != nil {
return diag.FromErr(err)
}

var tfState struct {
Lineage string `json:"lineage"`
Serial int `json:"serial"`
}
if err := json.Unmarshal(data, &tfState); err != nil {
return diag.FromErr(err)
return false, diag.FromErr(err)
}

migratedDB := dstate.NewDatabase(tfState.Lineage, tfState.Serial+1)
Expand All @@ -141,26 +150,27 @@ func (m *uploadStateForYamlSync) convertState(ctx context.Context, b *bundle.Bun
interpolatedRoot := b.Config.Value()
uninterpolatedRoot, err := reverseInterpolate(interpolatedRoot)
if err != nil {
return diag.FromErr(fmt.Errorf("failed to reverse interpolation: %w", err))
return false, diag.FromErr(fmt.Errorf("failed to reverse interpolation: %w", err))
}

var uninterpolatedConfig config.Root
err = uninterpolatedConfig.Mutate(func(_ dyn.Value) (dyn.Value, error) {
return uninterpolatedRoot, nil
})
if err != nil {
return diag.FromErr(fmt.Errorf("failed to create uninterpolated config: %w", err))
return false, diag.FromErr(fmt.Errorf("failed to create uninterpolated config: %w", err))
}

plan, err := deploymentBundle.CalculatePlan(ctx, b.WorkspaceClient(), &uninterpolatedConfig, snapshotPath)
if err != nil {
return diag.FromErr(err)
return false, diag.FromErr(err)
}

for _, entry := range plan.Plan {
entry.Action = deployplan.Update
}

var diags diag.Diagnostics
for key := range plan.Plan {
etag := etags[key]
if etag == "" {
Expand All @@ -178,7 +188,7 @@ func (m *uploadStateForYamlSync) convertState(ctx context.Context, b *bundle.Bun

deploymentBundle.Apply(ctx, b.WorkspaceClient(), plan, direct.MigrateMode(true))

return diags
return true, diags
}

// reverseInterpolate reverses the terraform.Interpolate transformation.
Expand Down
Loading