in astro/terraform/terraform_plan.go [25:86]
func (s *Session) Plan() (Result, error) {
if !s.Initialized() {
if result, err := s.Init(); err != nil {
return result, err
}
}
args := []string{"plan", "-detailed-exitcode", fmt.Sprintf("-out=%s.plan", s.id)}
for key, val := range s.config.Variables {
args = append(args, "-var", fmt.Sprintf("%s=%s", key, val))
}
args = append(args, s.config.TerraformParameters...)
process, err := s.terraformCommand(args, []int{0, 2})
if err != nil {
return nil, err
}
if err := process.Run(); err != nil {
return &terraformResult{
process: process,
}, err
}
var changes string
// With -detailed-exitcode, plans that return exit code 2 mean there
// are changes (so there's no error).
if process.ExitCode() == 2 {
// Fetch changes
terraformVersion, err := s.versionCached()
if err != nil {
return nil, err
}
if VersionMatches(terraformVersion, "<0.12") {
result, err := s.Show(fmt.Sprintf("%s.plan", s.id))
if err != nil {
return result, err
}
changes = result.Stdout()
} else {
rawPlanOutput := process.Stdout().String()
var re = regexp.MustCompile(`(?s)Terraform will perform the following actions:(.*)-{72}`)
if match := re.FindStringSubmatch(rawPlanOutput); len(match) == 2 {
changes = match[1]
} else {
return &terraformResult{
process: process,
}, fmt.Errorf("unable to parse terraform plan output")
}
}
}
return &PlanResult{
terraformResult: &terraformResult{
process: process,
},
changes: changes,
}, nil
}