func ReadProviderConfigValues(data []byte, kind, name string) (map[string]interface{}, error) {
	p := new(plan)
	if err := json.Unmarshal(data, p); err != nil {
		return nil, err
	}
	result := make(map[string]interface{})
	config, ok := resourceProviderConfig(kind, name, p)
	if !ok {
		return result, nil
	}
	for k, v := range config.Expressions {
		switch mv := v.(type) {
		case map[string]interface{}:
			result[k] = resolveExpression(mv, p)
		}
	}
	return result, nil
}
ReadProviderConfigValues returns the values from the expressions block from the provider config for the resource with the given kind and name.
Variable references are resolved, as are constant_value.
package terraform
import (
	"encoding/json"
	"strings"
)
type plan struct {
	Variables       map[string]variable `json:"variables"`
	PlannedValues   values              `json:"planned_values"`
	ResourceChanges []ResourceChange    `json:"resource_changes"`
	Configuration   Configuration       `json:"configuration"`
}
type variable struct {
	Value interface{} `json:"value"`
}
type values struct {
	RootModules struct {
		Resources    []Resource    `json:"resources"`
		ChildModules []childModule `json:"child_modules"`
	} `json:"root_module"`
}
type childModule struct {
	Address      string        `json:"address"`
	Resources    []Resource    `json:"resources"`
	ChildModules []childModule `json:"child_modules"`
}
type Resource struct {
	Name    string                 `json:"name"`
	Address string                 `json:"address"`
	Kind    string                 `json:"type"`
	Mode    string                 `json:"mode"`  
	Values  map[string]interface{} `json:"values"`
}
type ResourceChange struct {
	Address       string `json:"address"`
	ModuleAddress string `json:"module_address"`
	Mode          string `json:"mode"`  
	Kind          string `json:"type"`
	Name          string `json:"name"`
	Change        Change `json:"change"`
}
type Change struct {
	Actions []string `json:"actions"`
	Before       map[string]interface{} `json:"before"`
	After        map[string]interface{} `json:"after"`
	AfterUnknown map[string]interface{} `json:"after_unknown"`  
}
type Configuration struct {
	ProviderConfig map[string]ProviderConfig `json:"provider_config"`
	RootModule     struct {
		Resources []struct {
			Address           string      `json:"address"`
			Kind              string      `json:"type"`
			Name              string      `json:"name"`
			ProviderConfigKey string      `json:"provider_config_key"`
			Expressions       expressions `json:"expressions"`
		} `json:"resources"`
	} `json:"root_module"`
}
type ProviderConfig struct {
	Name              string      `json:"name"`
	VersionConstraint string      `json:"version_constraint,omitempty"`
	Alias             string      `json:"alias,omitempty"`
	Expressions       expressions `json:"expressions"`
}
type expressions map[string]interface{}
func ReadPlanChanges(data []byte, actions []string) ([]ResourceChange, error) {
	p := new(plan)
	if err := json.Unmarshal(data, p); err != nil {
		return nil, err
	}
	var result []ResourceChange
	for _, rc := range p.ResourceChanges {
		if len(actions) == 0 || slicesEqual(rc.Change.Actions, actions) {
			result = append(result, rc)
		}
	}
	return result, nil
}
func slicesEqual(a, b []string) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}