-
Notifications
You must be signed in to change notification settings - Fork 563
/
Copy pathterragrunt.go
124 lines (103 loc) · 3.58 KB
/
terragrunt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package execution
import (
"bytes"
"fmt"
"io"
"log"
"os"
"os/exec"
"strings"
)
type Terragrunt struct {
WorkingDir string
}
func (terragrunt Terragrunt) Init(params []string, envs map[string]string) (string, string, error) {
stdout, stderr, exitCode, err := terragrunt.runTerragruntCommand("init", true, envs, params...)
if exitCode != 0 {
logCommandFail(exitCode, err)
}
return stdout, stderr, err
}
func (terragrunt Terragrunt) Apply(params []string, plan *string, envs map[string]string) (string, string, error) {
params = append(params, []string{"-lock-timeout=3m"}...)
params = append(params, "--auto-approve")
params = append(params, "--terragrunt-non-interactive")
if plan != nil {
params = append(params, *plan)
}
stdout, stderr, exitCode, err := terragrunt.runTerragruntCommand("apply", true, envs, params...)
if exitCode != 0 {
logCommandFail(exitCode, err)
}
return stdout, stderr, err
}
func (terragrunt Terragrunt) Destroy(params []string, envs map[string]string) (string, string, error) {
params = append(params, "--auto-approve")
params = append(params, "--terragrunt-non-interactive")
stdout, stderr, exitCode, err := terragrunt.runTerragruntCommand("destroy", true, envs, params...)
if exitCode != 0 {
logCommandFail(exitCode, err)
}
return stdout, stderr, err
}
func (terragrunt Terragrunt) Plan(params []string, envs map[string]string, planArtefactFilePath string) (bool, string, string, error) {
if planArtefactFilePath != "" {
params = append(params, []string{"-out", planArtefactFilePath}...)
}
params = append(params, "-lock-timeout=3m")
stdout, stderr, exitCode, err := terragrunt.runTerragruntCommand("plan", true, envs, params...)
if exitCode != 0 {
logCommandFail(exitCode, err)
}
return true, stdout, stderr, err
}
func (terragrunt Terragrunt) Show(params []string, envs map[string]string, planArtefactFilePath string) (string, string, error) {
params = append(params, []string{"-no-color", "-json", planArtefactFilePath}...)
stdout, stderr, exitCode, err := terragrunt.runTerragruntCommand("show", false, envs, params...)
if exitCode != 0 {
logCommandFail(exitCode, err)
}
return stdout, stderr, err
}
func (terragrunt Terragrunt) runTerragruntCommand(command string, printOutputToStdout bool, envs map[string]string, arg ...string) (stdOut string, stdErr string, exitCode int, err error) {
args := []string{command}
args = append(args, arg...)
expandedArgs := make([]string, 0)
for _, p := range args {
s := os.ExpandEnv(p)
s = strings.TrimSpace(s)
if s != "" {
expandedArgs = append(expandedArgs, s)
}
}
// Set up common output buffers
var mwout, mwerr io.Writer
var stdout, stderr bytes.Buffer
if printOutputToStdout {
mwout = io.MultiWriter(os.Stdout, &stdout)
mwerr = io.MultiWriter(os.Stderr, &stderr)
} else {
mwout = io.Writer(&stdout)
mwerr = io.Writer(&stderr)
}
cmd := exec.Command("terragrunt", args...)
log.Printf("Running command: terragrunt %v", expandedArgs)
cmd.Dir = terragrunt.WorkingDir
env := os.Environ()
env = append(env, "TF_CLI_ARGS=-no-color")
env = append(env, "TF_IN_AUTOMATION=true")
env = append(env, "TERRAGRUNT_FORWARD_TF_STDOUT=1")
env = append(env, "TERRAGRUNT_NO_COLOR=true")
env = append(env, "TERRAGRUNT_NON_INTERACTIVE=true")
env = append(env, "TG_NO_COLOR=true")
env = append(env, "TG_NON_INTERACTIVE=true")
env = append(env, "TG_TF_FORWARD_STDOUT=true")
for k, v := range envs {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
cmd.Env = env
cmd.Stdout = mwout
cmd.Stderr = mwerr
err = cmd.Run()
return stdout.String(), stderr.String(), cmd.ProcessState.ExitCode(), err
}