github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/terraform/data_source_state.go (about) 1 package terraform 2 3 import ( 4 "log" 5 "time" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 "github.com/hashicorp/terraform/state/remote" 9 ) 10 11 func dataSourceRemoteState() *schema.Resource { 12 return &schema.Resource{ 13 Read: dataSourceRemoteStateRead, 14 15 Schema: map[string]*schema.Schema{ 16 "backend": { 17 Type: schema.TypeString, 18 Required: true, 19 ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { 20 if vStr, ok := v.(string); ok && vStr == "_local" { 21 ws = append(ws, "Use of the %q backend is now officially "+ 22 "supported as %q. Please update your configuration to ensure "+ 23 "compatibility with future versions of Terraform.", 24 "_local", "local") 25 } 26 27 return 28 }, 29 }, 30 31 "config": { 32 Type: schema.TypeMap, 33 Optional: true, 34 }, 35 36 "__has_dynamic_attributes": { 37 Type: schema.TypeString, 38 Optional: true, 39 }, 40 }, 41 } 42 } 43 44 func dataSourceRemoteStateRead(d *schema.ResourceData, meta interface{}) error { 45 backend := d.Get("backend").(string) 46 config := make(map[string]string) 47 for k, v := range d.Get("config").(map[string]interface{}) { 48 config[k] = v.(string) 49 } 50 51 // Don't break people using the old _local syntax - but note warning above 52 if backend == "_local" { 53 log.Println(`[INFO] Switching old (unsupported) backend "_local" to "local"`) 54 backend = "local" 55 } 56 57 // Create the client to access our remote state 58 log.Printf("[DEBUG] Initializing remote state client: %s", backend) 59 client, err := remote.NewClient(backend, config) 60 if err != nil { 61 return err 62 } 63 64 // Create the remote state itself and refresh it in order to load the state 65 log.Printf("[DEBUG] Loading remote state...") 66 state := &remote.State{Client: client} 67 if err := state.RefreshState(); err != nil { 68 return err 69 } 70 71 d.SetId(time.Now().UTC().String()) 72 73 outputMap := make(map[string]interface{}) 74 75 remoteState := state.State() 76 if remoteState.Empty() { 77 log.Println("[DEBUG] empty remote state") 78 return nil 79 } 80 81 for key, val := range remoteState.RootModule().Outputs { 82 outputMap[key] = val.Value 83 } 84 85 mappedOutputs := remoteStateFlatten(outputMap) 86 87 for key, val := range mappedOutputs { 88 d.UnsafeSetFieldRaw(key, val) 89 } 90 return nil 91 }