github.com/databricks/cli@v0.203.0/bundle/deploy/terraform/plan.go (about)

     1  package terraform
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"path/filepath"
     7  
     8  	"github.com/databricks/cli/bundle"
     9  	"github.com/databricks/cli/libs/cmdio"
    10  	"github.com/databricks/cli/libs/terraform"
    11  	"github.com/hashicorp/terraform-exec/tfexec"
    12  )
    13  
    14  type PlanGoal string
    15  
    16  var (
    17  	PlanDeploy  = PlanGoal("deploy")
    18  	PlanDestroy = PlanGoal("destroy")
    19  )
    20  
    21  type plan struct {
    22  	goal PlanGoal
    23  }
    24  
    25  func (p *plan) Name() string {
    26  	return "terraform.Plan"
    27  }
    28  
    29  func (p *plan) Apply(ctx context.Context, b *bundle.Bundle) error {
    30  	tf := b.Terraform
    31  	if tf == nil {
    32  		return fmt.Errorf("terraform not initialized")
    33  	}
    34  
    35  	cmdio.LogString(ctx, "Starting plan computation")
    36  
    37  	err := tf.Init(ctx, tfexec.Upgrade(true))
    38  	if err != nil {
    39  		return fmt.Errorf("terraform init: %w", err)
    40  	}
    41  
    42  	// Persist computed plan
    43  	tfDir, err := Dir(b)
    44  	if err != nil {
    45  		return err
    46  	}
    47  	planPath := filepath.Join(tfDir, "plan")
    48  	destroy := p.goal == PlanDestroy
    49  
    50  	notEmpty, err := tf.Plan(ctx, tfexec.Destroy(destroy), tfexec.Out(planPath))
    51  	if err != nil {
    52  		return err
    53  	}
    54  
    55  	// Set plan in main bundle struct for downstream mutators
    56  	b.Plan = &terraform.Plan{
    57  		Path:         planPath,
    58  		ConfirmApply: b.AutoApprove,
    59  		IsEmpty:      !notEmpty,
    60  	}
    61  
    62  	cmdio.LogString(ctx, fmt.Sprintf("Planning complete and persisted at %s\n", planPath))
    63  	return nil
    64  }
    65  
    66  // Plan returns a [bundle.Mutator] that runs the equivalent of `terraform plan -out ./plan`
    67  // from the bundle's ephemeral working directory for Terraform.
    68  func Plan(goal PlanGoal) bundle.Mutator {
    69  	return &plan{
    70  		goal: goal,
    71  	}
    72  }