func (t *Terraform) Execute(commandRaw ...string) error {
	command := make([]string, 1, len(commandRaw)*2)
	command[0] = commandRaw[0]
	commandArgs := commandRaw[1:]
	varSkip := false
	varSkip = command[0] == "get"
	if !varSkip && len(t.Variables) > 0 {
		varfile, err := t.varfile()
		if err != nil {
			return err
		}
		if execHelper.ShouldCleanup() {
			defer os.Remove(varfile)
		}
		command = append(command, "-var-file", varfile)
		for k, _ := range t.Variables {
			log.Printf("[DEBUG] setting TF var: %s", k)
		}
	}
	stateSkip := false
	stateSkip = command[0] == "get"
	stateOutSkip := false
	var stateDir, statePath string
	if !stateSkip && t.StateId != "" && t.Directory != nil {
		stateDir = t.Dir
		stateOldPath := filepath.Join(stateDir, "state.old")
		statePath = filepath.Join(stateDir, "state")
		data, err := t.Directory.GetBlob(t.StateId)
		if err != nil {
			return fmt.Errorf("Error loading Terraform state: %s", err)
		}
		if data == nil && command[0] == "destroy" {
			return nil
		}
		if data != nil {
			err = data.WriteToFile(stateOldPath)
			data.Close()
		}
		if err != nil {
			return fmt.Errorf("Error writing Terraform state: %s", err)
		}
		command = append(command, "-state", stateOldPath)
		if command[0] == "apply" {
			command = append(command, "-state-out", statePath)
		}
	}
	command = append(command, commandArgs...)
	command = append(command, "-no-color")
	log.Printf("[DEBUG] executing terraform: %v", command)
	path := "terraform"
	if t.Path != "" {
		path = t.Path
	}
	cmd := exec.Command(path, "get")
	cmd.Dir = t.Dir
	err := execHelper.Run(t.Ui, cmd)
	if err != nil {
		err = fmt.Errorf("Error running Terraform for getting modules: %s", err)
	}
	buildModulesScript := "if ls -1 .terraform/modules/*/Makefile >/dev/null 2>&1; then for dir in .terraform/modules/*/Makefile; do make -C $(/usr/bin/dirname $dir); done fi"
	cmd = exec.Command("/bin/bash", "-c", buildModulesScript)
	cmd.Dir = t.Dir
	err = execHelper.Run(t.Ui, cmd)
	if err != nil {
		err = fmt.Errorf("Error running Terraform for getting modules: %s", err)
	}
	cmd = exec.Command(path, command...)
	cmd.Dir = t.Dir
	err = execHelper.Run(t.Ui, cmd)
	if err != nil {
		err = fmt.Errorf("Error running Terraform: %s", err)
	}
	if command[0] == "apply" && t.StateId != "" && t.Directory != nil && statePath != "" && !stateOutSkip {
		f, ferr := os.Open(statePath)
		if ferr != nil {
			return fmt.Errorf(
				"Error reading Terraform state for saving: %s", ferr)
		}
		derr := t.Directory.PutBlob(t.StateId, &persistence.BlobData{
			Data: f,
		})
		f.Close()
		if derr != nil {
			err = fmt.Errorf(
				"Failed to save Terraform state: %s\n\n"+
					"This means that Otto was unable to store the state of your infrastructure.\n"+
					"At this time, Otto doesn't support gracefully recovering from this\n"+
					"scenario. The state should be in the path below. Please ask the\n"+
					"community for assistance.",
				derr)
		}
	}
	return err
}
Execute executes a raw Terraform command
package terraform
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"github.com/capgemini/terraform-control/persistence"
	"github.com/hashicorp/go-version"
	execHelper "github.com/hashicorp/otto/helper/exec"
	"github.com/hashicorp/otto/ui"
)
var (
	tfMinVersion = version.Must(version.NewVersion("0.6.3"))
)
type Terraform struct {
	Path string
	Dir string
	Ui ui.Ui
	Variables map[string]string
	Directory persistence.Backend
	StateId string
}