func()

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
}