github.com/pbthorste/terraform@v0.8.6-0.20170127005045-deb56bd93da2/terraform/state.go (about) 1 package terraform 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io" 9 "io/ioutil" 10 "log" 11 "reflect" 12 "regexp" 13 "sort" 14 "strconv" 15 "strings" 16 "sync" 17 18 "github.com/hashicorp/go-multierror" 19 "github.com/hashicorp/go-version" 20 "github.com/hashicorp/terraform/config" 21 "github.com/mitchellh/copystructure" 22 "github.com/satori/go.uuid" 23 ) 24 25 const ( 26 // StateVersion is the current version for our state file 27 StateVersion = 3 28 ) 29 30 // rootModulePath is the path of the root module 31 var rootModulePath = []string{"root"} 32 33 // normalizeModulePath takes a raw module path and returns a path that 34 // has the rootModulePath prepended to it. If I could go back in time I 35 // would've never had a rootModulePath (empty path would be root). We can 36 // still fix this but thats a big refactor that my branch doesn't make sense 37 // for. Instead, this function normalizes paths. 38 func normalizeModulePath(p []string) []string { 39 k := len(rootModulePath) 40 41 // If we already have a root module prefix, we're done 42 if len(p) >= len(rootModulePath) { 43 if reflect.DeepEqual(p[:k], rootModulePath) { 44 return p 45 } 46 } 47 48 // None? Prefix it 49 result := make([]string, len(rootModulePath)+len(p)) 50 copy(result, rootModulePath) 51 copy(result[k:], p) 52 return result 53 } 54 55 // State keeps track of a snapshot state-of-the-world that Terraform 56 // can use to keep track of what real world resources it is actually 57 // managing. 58 type State struct { 59 // Version is the state file protocol version. 60 Version int `json:"version"` 61 62 // TFVersion is the version of Terraform that wrote this state. 63 TFVersion string `json:"terraform_version,omitempty"` 64 65 // Serial is incremented on any operation that modifies 66 // the State file. It is used to detect potentially conflicting 67 // updates. 68 Serial int64 `json:"serial"` 69 70 // Lineage is set when a new, blank state is created and then 71 // never updated. This allows us to determine whether the serials 72 // of two states can be meaningfully compared. 73 // Apart from the guarantee that collisions between two lineages 74 // are very unlikely, this value is opaque and external callers 75 // should only compare lineage strings byte-for-byte for equality. 76 Lineage string `json:"lineage"` 77 78 // Remote is used to track the metadata required to 79 // pull and push state files from a remote storage endpoint. 80 Remote *RemoteState `json:"remote,omitempty"` 81 82 // Backend tracks the configuration for the backend in use with 83 // this state. This is used to track any changes in the backend 84 // configuration. 85 Backend *BackendState `json:"backend,omitempty"` 86 87 // Modules contains all the modules in a breadth-first order 88 Modules []*ModuleState `json:"modules"` 89 90 mu sync.Mutex 91 } 92 93 func (s *State) Lock() { s.mu.Lock() } 94 func (s *State) Unlock() { s.mu.Unlock() } 95 96 // NewState is used to initialize a blank state 97 func NewState() *State { 98 s := &State{} 99 s.init() 100 return s 101 } 102 103 // Children returns the ModuleStates that are direct children of 104 // the given path. If the path is "root", for example, then children 105 // returned might be "root.child", but not "root.child.grandchild". 106 func (s *State) Children(path []string) []*ModuleState { 107 s.Lock() 108 defer s.Unlock() 109 // TODO: test 110 111 return s.children(path) 112 } 113 114 func (s *State) children(path []string) []*ModuleState { 115 result := make([]*ModuleState, 0) 116 for _, m := range s.Modules { 117 if m == nil { 118 continue 119 } 120 121 if len(m.Path) != len(path)+1 { 122 continue 123 } 124 if !reflect.DeepEqual(path, m.Path[:len(path)]) { 125 continue 126 } 127 128 result = append(result, m) 129 } 130 131 return result 132 } 133 134 // AddModule adds the module with the given path to the state. 135 // 136 // This should be the preferred method to add module states since it 137 // allows us to optimize lookups later as well as control sorting. 138 func (s *State) AddModule(path []string) *ModuleState { 139 s.Lock() 140 defer s.Unlock() 141 142 return s.addModule(path) 143 } 144 145 func (s *State) addModule(path []string) *ModuleState { 146 // check if the module exists first 147 m := s.moduleByPath(path) 148 if m != nil { 149 return m 150 } 151 152 m = &ModuleState{Path: path} 153 m.init() 154 s.Modules = append(s.Modules, m) 155 s.sort() 156 return m 157 } 158 159 // ModuleByPath is used to lookup the module state for the given path. 160 // This should be the preferred lookup mechanism as it allows for future 161 // lookup optimizations. 162 func (s *State) ModuleByPath(path []string) *ModuleState { 163 if s == nil { 164 return nil 165 } 166 s.Lock() 167 defer s.Unlock() 168 169 return s.moduleByPath(path) 170 } 171 172 func (s *State) moduleByPath(path []string) *ModuleState { 173 for _, mod := range s.Modules { 174 if mod == nil { 175 continue 176 } 177 if mod.Path == nil { 178 panic("missing module path") 179 } 180 if reflect.DeepEqual(mod.Path, path) { 181 return mod 182 } 183 } 184 return nil 185 } 186 187 // ModuleOrphans returns all the module orphans in this state by 188 // returning their full paths. These paths can be used with ModuleByPath 189 // to return the actual state. 190 func (s *State) ModuleOrphans(path []string, c *config.Config) [][]string { 191 s.Lock() 192 defer s.Unlock() 193 194 return s.moduleOrphans(path, c) 195 196 } 197 198 func (s *State) moduleOrphans(path []string, c *config.Config) [][]string { 199 // direct keeps track of what direct children we have both in our config 200 // and in our state. childrenKeys keeps track of what isn't an orphan. 201 direct := make(map[string]struct{}) 202 childrenKeys := make(map[string]struct{}) 203 if c != nil { 204 for _, m := range c.Modules { 205 childrenKeys[m.Name] = struct{}{} 206 direct[m.Name] = struct{}{} 207 } 208 } 209 210 // Go over the direct children and find any that aren't in our keys. 211 var orphans [][]string 212 for _, m := range s.children(path) { 213 key := m.Path[len(m.Path)-1] 214 215 // Record that we found this key as a direct child. We use this 216 // later to find orphan nested modules. 217 direct[key] = struct{}{} 218 219 // If we have a direct child still in our config, it is not an orphan 220 if _, ok := childrenKeys[key]; ok { 221 continue 222 } 223 224 orphans = append(orphans, m.Path) 225 } 226 227 // Find the orphans that are nested... 228 for _, m := range s.Modules { 229 if m == nil { 230 continue 231 } 232 233 // We only want modules that are at least grandchildren 234 if len(m.Path) < len(path)+2 { 235 continue 236 } 237 238 // If it isn't part of our tree, continue 239 if !reflect.DeepEqual(path, m.Path[:len(path)]) { 240 continue 241 } 242 243 // If we have the direct child, then just skip it. 244 key := m.Path[len(path)] 245 if _, ok := direct[key]; ok { 246 continue 247 } 248 249 orphanPath := m.Path[:len(path)+1] 250 251 // Don't double-add if we've already added this orphan (which can happen if 252 // there are multiple nested sub-modules that get orphaned together). 253 alreadyAdded := false 254 for _, o := range orphans { 255 if reflect.DeepEqual(o, orphanPath) { 256 alreadyAdded = true 257 break 258 } 259 } 260 if alreadyAdded { 261 continue 262 } 263 264 // Add this orphan 265 orphans = append(orphans, orphanPath) 266 } 267 268 return orphans 269 } 270 271 // Empty returns true if the state is empty. 272 func (s *State) Empty() bool { 273 if s == nil { 274 return true 275 } 276 s.Lock() 277 defer s.Unlock() 278 279 return len(s.Modules) == 0 280 } 281 282 // HasResources returns true if the state contains any resources. 283 // 284 // This is similar to !s.Empty, but returns true also in the case where the 285 // state has modules but all of them are devoid of resources. 286 func (s *State) HasResources() bool { 287 if s.Empty() { 288 return false 289 } 290 291 for _, mod := range s.Modules { 292 if len(mod.Resources) > 0 { 293 return true 294 } 295 } 296 297 return false 298 } 299 300 // IsRemote returns true if State represents a state that exists and is 301 // remote. 302 func (s *State) IsRemote() bool { 303 if s == nil { 304 return false 305 } 306 s.Lock() 307 defer s.Unlock() 308 309 if s.Remote == nil { 310 return false 311 } 312 if s.Remote.Type == "" { 313 return false 314 } 315 316 return true 317 } 318 319 // Validate validates the integrity of this state file. 320 // 321 // Certain properties of the statefile are expected by Terraform in order 322 // to behave properly. The core of Terraform will assume that once it 323 // receives a State structure that it has been validated. This validation 324 // check should be called to ensure that. 325 // 326 // If this returns an error, then the user should be notified. The error 327 // response will include detailed information on the nature of the error. 328 func (s *State) Validate() error { 329 s.Lock() 330 defer s.Unlock() 331 332 var result error 333 334 // !!!! FOR DEVELOPERS !!!! 335 // 336 // Any errors returned from this Validate function will BLOCK TERRAFORM 337 // from loading a state file. Therefore, this should only contain checks 338 // that are only resolvable through manual intervention. 339 // 340 // !!!! FOR DEVELOPERS !!!! 341 342 // Make sure there are no duplicate module states. We open a new 343 // block here so we can use basic variable names and future validations 344 // can do the same. 345 { 346 found := make(map[string]struct{}) 347 for _, ms := range s.Modules { 348 if ms == nil { 349 continue 350 } 351 352 key := strings.Join(ms.Path, ".") 353 if _, ok := found[key]; ok { 354 result = multierror.Append(result, fmt.Errorf( 355 strings.TrimSpace(stateValidateErrMultiModule), key)) 356 continue 357 } 358 359 found[key] = struct{}{} 360 } 361 } 362 363 return result 364 } 365 366 // Remove removes the item in the state at the given address, returning 367 // any errors that may have occurred. 368 // 369 // If the address references a module state or resource, it will delete 370 // all children as well. To check what will be deleted, use a StateFilter 371 // first. 372 func (s *State) Remove(addr ...string) error { 373 s.Lock() 374 defer s.Unlock() 375 376 // Filter out what we need to delete 377 filter := &StateFilter{State: s} 378 results, err := filter.Filter(addr...) 379 if err != nil { 380 return err 381 } 382 383 // If we have no results, just exit early, we're not going to do anything. 384 // While what happens below is fairly fast, this is an important early 385 // exit since the prune below might modify the state more and we don't 386 // want to modify the state if we don't have to. 387 if len(results) == 0 { 388 return nil 389 } 390 391 // Go through each result and grab what we need 392 removed := make(map[interface{}]struct{}) 393 for _, r := range results { 394 // Convert the path to our own type 395 path := append([]string{"root"}, r.Path...) 396 397 // If we removed this already, then ignore 398 if _, ok := removed[r.Value]; ok { 399 continue 400 } 401 402 // If we removed the parent already, then ignore 403 if r.Parent != nil { 404 if _, ok := removed[r.Parent.Value]; ok { 405 continue 406 } 407 } 408 409 // Add this to the removed list 410 removed[r.Value] = struct{}{} 411 412 switch v := r.Value.(type) { 413 case *ModuleState: 414 s.removeModule(path, v) 415 case *ResourceState: 416 s.removeResource(path, v) 417 case *InstanceState: 418 s.removeInstance(path, r.Parent.Value.(*ResourceState), v) 419 default: 420 return fmt.Errorf("unknown type to delete: %T", r.Value) 421 } 422 } 423 424 // Prune since the removal functions often do the bare minimum to 425 // remove a thing and may leave around dangling empty modules, resources, 426 // etc. Prune will clean that all up. 427 s.prune() 428 429 return nil 430 } 431 432 func (s *State) removeModule(path []string, v *ModuleState) { 433 for i, m := range s.Modules { 434 if m == v { 435 s.Modules, s.Modules[len(s.Modules)-1] = append(s.Modules[:i], s.Modules[i+1:]...), nil 436 return 437 } 438 } 439 } 440 441 func (s *State) removeResource(path []string, v *ResourceState) { 442 // Get the module this resource lives in. If it doesn't exist, we're done. 443 mod := s.moduleByPath(path) 444 if mod == nil { 445 return 446 } 447 448 // Find this resource. This is a O(N) lookup when if we had the key 449 // it could be O(1) but even with thousands of resources this shouldn't 450 // matter right now. We can easily up performance here when the time comes. 451 for k, r := range mod.Resources { 452 if r == v { 453 // Found it 454 delete(mod.Resources, k) 455 return 456 } 457 } 458 } 459 460 func (s *State) removeInstance(path []string, r *ResourceState, v *InstanceState) { 461 // Go through the resource and find the instance that matches this 462 // (if any) and remove it. 463 464 // Check primary 465 if r.Primary == v { 466 r.Primary = nil 467 return 468 } 469 470 // Check lists 471 lists := [][]*InstanceState{r.Deposed} 472 for _, is := range lists { 473 for i, instance := range is { 474 if instance == v { 475 // Found it, remove it 476 is, is[len(is)-1] = append(is[:i], is[i+1:]...), nil 477 478 // Done 479 return 480 } 481 } 482 } 483 } 484 485 // RootModule returns the ModuleState for the root module 486 func (s *State) RootModule() *ModuleState { 487 root := s.ModuleByPath(rootModulePath) 488 if root == nil { 489 panic("missing root module") 490 } 491 return root 492 } 493 494 // Equal tests if one state is equal to another. 495 func (s *State) Equal(other *State) bool { 496 // If one is nil, we do a direct check 497 if s == nil || other == nil { 498 return s == other 499 } 500 501 s.Lock() 502 defer s.Unlock() 503 return s.equal(other) 504 } 505 506 func (s *State) equal(other *State) bool { 507 if s == nil || other == nil { 508 return s == other 509 } 510 511 // If the versions are different, they're certainly not equal 512 if s.Version != other.Version { 513 return false 514 } 515 516 // If any of the modules are not equal, then this state isn't equal 517 if len(s.Modules) != len(other.Modules) { 518 return false 519 } 520 for _, m := range s.Modules { 521 // This isn't very optimal currently but works. 522 otherM := other.moduleByPath(m.Path) 523 if otherM == nil { 524 return false 525 } 526 527 // If they're not equal, then we're not equal! 528 if !m.Equal(otherM) { 529 return false 530 } 531 } 532 533 return true 534 } 535 536 type StateAgeComparison int 537 538 const ( 539 StateAgeEqual StateAgeComparison = 0 540 StateAgeReceiverNewer StateAgeComparison = 1 541 StateAgeReceiverOlder StateAgeComparison = -1 542 ) 543 544 // CompareAges compares one state with another for which is "older". 545 // 546 // This is a simple check using the state's serial, and is thus only as 547 // reliable as the serial itself. In the normal case, only one state 548 // exists for a given combination of lineage/serial, but Terraform 549 // does not guarantee this and so the result of this method should be 550 // used with care. 551 // 552 // Returns an integer that is negative if the receiver is older than 553 // the argument, positive if the converse, and zero if they are equal. 554 // An error is returned if the two states are not of the same lineage, 555 // in which case the integer returned has no meaning. 556 func (s *State) CompareAges(other *State) (StateAgeComparison, error) { 557 // nil states are "older" than actual states 558 switch { 559 case s != nil && other == nil: 560 return StateAgeReceiverNewer, nil 561 case s == nil && other != nil: 562 return StateAgeReceiverOlder, nil 563 case s == nil && other == nil: 564 return StateAgeEqual, nil 565 } 566 567 if !s.SameLineage(other) { 568 return StateAgeEqual, fmt.Errorf( 569 "can't compare two states of differing lineage", 570 ) 571 } 572 573 s.Lock() 574 defer s.Unlock() 575 576 switch { 577 case s.Serial < other.Serial: 578 return StateAgeReceiverOlder, nil 579 case s.Serial > other.Serial: 580 return StateAgeReceiverNewer, nil 581 default: 582 return StateAgeEqual, nil 583 } 584 } 585 586 // SameLineage returns true only if the state given in argument belongs 587 // to the same "lineage" of states as the reciever. 588 func (s *State) SameLineage(other *State) bool { 589 s.Lock() 590 defer s.Unlock() 591 592 // If one of the states has no lineage then it is assumed to predate 593 // this concept, and so we'll accept it as belonging to any lineage 594 // so that a lineage string can be assigned to newer versions 595 // without breaking compatibility with older versions. 596 if s.Lineage == "" || other.Lineage == "" { 597 return true 598 } 599 600 return s.Lineage == other.Lineage 601 } 602 603 // DeepCopy performs a deep copy of the state structure and returns 604 // a new structure. 605 func (s *State) DeepCopy() *State { 606 copy, err := copystructure.Config{Lock: true}.Copy(s) 607 if err != nil { 608 panic(err) 609 } 610 611 return copy.(*State) 612 } 613 614 // IncrementSerialMaybe increments the serial number of this state 615 // if it different from the other state. 616 func (s *State) IncrementSerialMaybe(other *State) { 617 if s == nil { 618 return 619 } 620 if other == nil { 621 return 622 } 623 s.Lock() 624 defer s.Unlock() 625 626 if s.Serial > other.Serial { 627 return 628 } 629 if other.TFVersion != s.TFVersion || !s.equal(other) { 630 if other.Serial > s.Serial { 631 s.Serial = other.Serial 632 } 633 634 s.Serial++ 635 } 636 } 637 638 // FromFutureTerraform checks if this state was written by a Terraform 639 // version from the future. 640 func (s *State) FromFutureTerraform() bool { 641 s.Lock() 642 defer s.Unlock() 643 644 // No TF version means it is certainly from the past 645 if s.TFVersion == "" { 646 return false 647 } 648 649 v := version.Must(version.NewVersion(s.TFVersion)) 650 return SemVersion.LessThan(v) 651 } 652 653 func (s *State) Init() { 654 s.Lock() 655 defer s.Unlock() 656 s.init() 657 } 658 659 func (s *State) init() { 660 if s.Version == 0 { 661 s.Version = StateVersion 662 } 663 if s.moduleByPath(rootModulePath) == nil { 664 s.addModule(rootModulePath) 665 } 666 s.ensureHasLineage() 667 668 for _, mod := range s.Modules { 669 if mod != nil { 670 mod.init() 671 } 672 } 673 674 if s.Remote != nil { 675 s.Remote.init() 676 } 677 678 } 679 680 func (s *State) EnsureHasLineage() { 681 s.Lock() 682 defer s.Unlock() 683 684 s.ensureHasLineage() 685 } 686 687 func (s *State) ensureHasLineage() { 688 if s.Lineage == "" { 689 s.Lineage = uuid.NewV4().String() 690 log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage) 691 } else { 692 log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage) 693 } 694 } 695 696 // AddModuleState insert this module state and override any existing ModuleState 697 func (s *State) AddModuleState(mod *ModuleState) { 698 mod.init() 699 s.Lock() 700 defer s.Unlock() 701 702 s.addModuleState(mod) 703 } 704 705 func (s *State) addModuleState(mod *ModuleState) { 706 for i, m := range s.Modules { 707 if reflect.DeepEqual(m.Path, mod.Path) { 708 s.Modules[i] = mod 709 return 710 } 711 } 712 713 s.Modules = append(s.Modules, mod) 714 s.sort() 715 } 716 717 // prune is used to remove any resources that are no longer required 718 func (s *State) prune() { 719 if s == nil { 720 return 721 } 722 723 // Filter out empty modules. 724 // A module is always assumed to have a path, and it's length isn't always 725 // bounds checked later on. Modules may be "emptied" during destroy, but we 726 // never want to store those in the state. 727 for i := 0; i < len(s.Modules); i++ { 728 if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 { 729 s.Modules = append(s.Modules[:i], s.Modules[i+1:]...) 730 i-- 731 } 732 } 733 734 for _, mod := range s.Modules { 735 mod.prune() 736 } 737 if s.Remote != nil && s.Remote.Empty() { 738 s.Remote = nil 739 } 740 } 741 742 // sort sorts the modules 743 func (s *State) sort() { 744 sort.Sort(moduleStateSort(s.Modules)) 745 746 // Allow modules to be sorted 747 for _, m := range s.Modules { 748 if m != nil { 749 m.sort() 750 } 751 } 752 } 753 754 func (s *State) String() string { 755 if s == nil { 756 return "<nil>" 757 } 758 s.Lock() 759 defer s.Unlock() 760 761 var buf bytes.Buffer 762 for _, m := range s.Modules { 763 mStr := m.String() 764 765 // If we're the root module, we just write the output directly. 766 if reflect.DeepEqual(m.Path, rootModulePath) { 767 buf.WriteString(mStr + "\n") 768 continue 769 } 770 771 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], "."))) 772 773 s := bufio.NewScanner(strings.NewReader(mStr)) 774 for s.Scan() { 775 text := s.Text() 776 if text != "" { 777 text = " " + text 778 } 779 780 buf.WriteString(fmt.Sprintf("%s\n", text)) 781 } 782 } 783 784 return strings.TrimSpace(buf.String()) 785 } 786 787 // BackendState stores the configuration to connect to a remote backend. 788 type BackendState struct { 789 Type string `json:"type"` // Backend type 790 Config map[string]interface{} `json:"config"` // Backend raw config 791 792 // Hash is the hash code to uniquely identify the original source 793 // configuration. We use this to detect when there is a change in 794 // configuration even when "type" isn't changed. 795 Hash uint64 `json:"hash"` 796 } 797 798 // Empty returns true if BackendState has no state. 799 func (s *BackendState) Empty() bool { 800 return s == nil || s.Type == "" 801 } 802 803 // RemoteState is used to track the information about a remote 804 // state store that we push/pull state to. 805 type RemoteState struct { 806 // Type controls the client we use for the remote state 807 Type string `json:"type"` 808 809 // Config is used to store arbitrary configuration that 810 // is type specific 811 Config map[string]string `json:"config"` 812 813 mu sync.Mutex 814 } 815 816 func (s *RemoteState) Lock() { s.mu.Lock() } 817 func (s *RemoteState) Unlock() { s.mu.Unlock() } 818 819 func (r *RemoteState) init() { 820 r.Lock() 821 defer r.Unlock() 822 823 if r.Config == nil { 824 r.Config = make(map[string]string) 825 } 826 } 827 828 func (r *RemoteState) deepcopy() *RemoteState { 829 r.Lock() 830 defer r.Unlock() 831 832 confCopy := make(map[string]string, len(r.Config)) 833 for k, v := range r.Config { 834 confCopy[k] = v 835 } 836 return &RemoteState{ 837 Type: r.Type, 838 Config: confCopy, 839 } 840 } 841 842 func (r *RemoteState) Empty() bool { 843 if r == nil { 844 return true 845 } 846 r.Lock() 847 defer r.Unlock() 848 849 return r.Type == "" 850 } 851 852 func (r *RemoteState) Equals(other *RemoteState) bool { 853 r.Lock() 854 defer r.Unlock() 855 856 if r.Type != other.Type { 857 return false 858 } 859 if len(r.Config) != len(other.Config) { 860 return false 861 } 862 for k, v := range r.Config { 863 if other.Config[k] != v { 864 return false 865 } 866 } 867 return true 868 } 869 870 // OutputState is used to track the state relevant to a single output. 871 type OutputState struct { 872 // Sensitive describes whether the output is considered sensitive, 873 // which may lead to masking the value on screen in some cases. 874 Sensitive bool `json:"sensitive"` 875 // Type describes the structure of Value. Valid values are "string", 876 // "map" and "list" 877 Type string `json:"type"` 878 // Value contains the value of the output, in the structure described 879 // by the Type field. 880 Value interface{} `json:"value"` 881 882 mu sync.Mutex 883 } 884 885 func (s *OutputState) Lock() { s.mu.Lock() } 886 func (s *OutputState) Unlock() { s.mu.Unlock() } 887 888 func (s *OutputState) String() string { 889 return fmt.Sprintf("%#v", s.Value) 890 } 891 892 // Equal compares two OutputState structures for equality. nil values are 893 // considered equal. 894 func (s *OutputState) Equal(other *OutputState) bool { 895 if s == nil && other == nil { 896 return true 897 } 898 899 if s == nil || other == nil { 900 return false 901 } 902 s.Lock() 903 defer s.Unlock() 904 905 if s.Type != other.Type { 906 return false 907 } 908 909 if s.Sensitive != other.Sensitive { 910 return false 911 } 912 913 if !reflect.DeepEqual(s.Value, other.Value) { 914 return false 915 } 916 917 return true 918 } 919 920 func (s *OutputState) deepcopy() *OutputState { 921 if s == nil { 922 return nil 923 } 924 925 stateCopy, err := copystructure.Config{Lock: true}.Copy(s) 926 if err != nil { 927 panic(fmt.Errorf("Error copying output value: %s", err)) 928 } 929 930 return stateCopy.(*OutputState) 931 } 932 933 // ModuleState is used to track all the state relevant to a single 934 // module. Previous to Terraform 0.3, all state belonged to the "root" 935 // module. 936 type ModuleState struct { 937 // Path is the import path from the root module. Modules imports are 938 // always disjoint, so the path represents amodule tree 939 Path []string `json:"path"` 940 941 // Outputs declared by the module and maintained for each module 942 // even though only the root module technically needs to be kept. 943 // This allows operators to inspect values at the boundaries. 944 Outputs map[string]*OutputState `json:"outputs"` 945 946 // Resources is a mapping of the logically named resource to 947 // the state of the resource. Each resource may actually have 948 // N instances underneath, although a user only needs to think 949 // about the 1:1 case. 950 Resources map[string]*ResourceState `json:"resources"` 951 952 // Dependencies are a list of things that this module relies on 953 // existing to remain intact. For example: an module may depend 954 // on a VPC ID given by an aws_vpc resource. 955 // 956 // Terraform uses this information to build valid destruction 957 // orders and to warn the user if they're destroying a module that 958 // another resource depends on. 959 // 960 // Things can be put into this list that may not be managed by 961 // Terraform. If Terraform doesn't find a matching ID in the 962 // overall state, then it assumes it isn't managed and doesn't 963 // worry about it. 964 Dependencies []string `json:"depends_on"` 965 966 mu sync.Mutex 967 } 968 969 func (s *ModuleState) Lock() { s.mu.Lock() } 970 func (s *ModuleState) Unlock() { s.mu.Unlock() } 971 972 // Equal tests whether one module state is equal to another. 973 func (m *ModuleState) Equal(other *ModuleState) bool { 974 m.Lock() 975 defer m.Unlock() 976 977 // Paths must be equal 978 if !reflect.DeepEqual(m.Path, other.Path) { 979 return false 980 } 981 982 // Outputs must be equal 983 if len(m.Outputs) != len(other.Outputs) { 984 return false 985 } 986 for k, v := range m.Outputs { 987 if !other.Outputs[k].Equal(v) { 988 return false 989 } 990 } 991 992 // Dependencies must be equal. This sorts these in place but 993 // this shouldn't cause any problems. 994 sort.Strings(m.Dependencies) 995 sort.Strings(other.Dependencies) 996 if len(m.Dependencies) != len(other.Dependencies) { 997 return false 998 } 999 for i, d := range m.Dependencies { 1000 if other.Dependencies[i] != d { 1001 return false 1002 } 1003 } 1004 1005 // Resources must be equal 1006 if len(m.Resources) != len(other.Resources) { 1007 return false 1008 } 1009 for k, r := range m.Resources { 1010 otherR, ok := other.Resources[k] 1011 if !ok { 1012 return false 1013 } 1014 1015 if !r.Equal(otherR) { 1016 return false 1017 } 1018 } 1019 1020 return true 1021 } 1022 1023 // IsRoot says whether or not this module diff is for the root module. 1024 func (m *ModuleState) IsRoot() bool { 1025 m.Lock() 1026 defer m.Unlock() 1027 return reflect.DeepEqual(m.Path, rootModulePath) 1028 } 1029 1030 // IsDescendent returns true if other is a descendent of this module. 1031 func (m *ModuleState) IsDescendent(other *ModuleState) bool { 1032 m.Lock() 1033 defer m.Unlock() 1034 1035 i := len(m.Path) 1036 return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path) 1037 } 1038 1039 // Orphans returns a list of keys of resources that are in the State 1040 // but aren't present in the configuration itself. Hence, these keys 1041 // represent the state of resources that are orphans. 1042 func (m *ModuleState) Orphans(c *config.Config) []string { 1043 m.Lock() 1044 defer m.Unlock() 1045 1046 keys := make(map[string]struct{}) 1047 for k, _ := range m.Resources { 1048 keys[k] = struct{}{} 1049 } 1050 1051 if c != nil { 1052 for _, r := range c.Resources { 1053 delete(keys, r.Id()) 1054 1055 for k, _ := range keys { 1056 if strings.HasPrefix(k, r.Id()+".") { 1057 delete(keys, k) 1058 } 1059 } 1060 } 1061 } 1062 1063 result := make([]string, 0, len(keys)) 1064 for k, _ := range keys { 1065 result = append(result, k) 1066 } 1067 1068 return result 1069 } 1070 1071 // View returns a view with the given resource prefix. 1072 func (m *ModuleState) View(id string) *ModuleState { 1073 if m == nil { 1074 return m 1075 } 1076 1077 r := m.deepcopy() 1078 for k, _ := range r.Resources { 1079 if id == k || strings.HasPrefix(k, id+".") { 1080 continue 1081 } 1082 1083 delete(r.Resources, k) 1084 } 1085 1086 return r 1087 } 1088 1089 func (m *ModuleState) init() { 1090 m.Lock() 1091 defer m.Unlock() 1092 1093 if m.Path == nil { 1094 m.Path = []string{} 1095 } 1096 if m.Outputs == nil { 1097 m.Outputs = make(map[string]*OutputState) 1098 } 1099 if m.Resources == nil { 1100 m.Resources = make(map[string]*ResourceState) 1101 } 1102 1103 if m.Dependencies == nil { 1104 m.Dependencies = make([]string, 0) 1105 } 1106 1107 for _, rs := range m.Resources { 1108 rs.init() 1109 } 1110 } 1111 1112 func (m *ModuleState) deepcopy() *ModuleState { 1113 if m == nil { 1114 return nil 1115 } 1116 1117 stateCopy, err := copystructure.Config{Lock: true}.Copy(m) 1118 if err != nil { 1119 panic(err) 1120 } 1121 1122 return stateCopy.(*ModuleState) 1123 } 1124 1125 // prune is used to remove any resources that are no longer required 1126 func (m *ModuleState) prune() { 1127 m.Lock() 1128 defer m.Unlock() 1129 1130 for k, v := range m.Resources { 1131 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 { 1132 delete(m.Resources, k) 1133 continue 1134 } 1135 1136 v.prune() 1137 } 1138 1139 for k, v := range m.Outputs { 1140 if v.Value == config.UnknownVariableValue { 1141 delete(m.Outputs, k) 1142 } 1143 } 1144 } 1145 1146 func (m *ModuleState) sort() { 1147 for _, v := range m.Resources { 1148 v.sort() 1149 } 1150 } 1151 1152 func (m *ModuleState) String() string { 1153 m.Lock() 1154 defer m.Unlock() 1155 1156 var buf bytes.Buffer 1157 1158 if len(m.Resources) == 0 { 1159 buf.WriteString("<no state>") 1160 } 1161 1162 names := make([]string, 0, len(m.Resources)) 1163 for name, _ := range m.Resources { 1164 names = append(names, name) 1165 } 1166 sort.Strings(names) 1167 1168 for _, k := range names { 1169 rs := m.Resources[k] 1170 var id string 1171 if rs.Primary != nil { 1172 id = rs.Primary.ID 1173 } 1174 if id == "" { 1175 id = "<not created>" 1176 } 1177 1178 taintStr := "" 1179 if rs.Primary.Tainted { 1180 taintStr = " (tainted)" 1181 } 1182 1183 deposedStr := "" 1184 if len(rs.Deposed) > 0 { 1185 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) 1186 } 1187 1188 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) 1189 buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) 1190 if rs.Provider != "" { 1191 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) 1192 } 1193 1194 var attributes map[string]string 1195 if rs.Primary != nil { 1196 attributes = rs.Primary.Attributes 1197 } 1198 attrKeys := make([]string, 0, len(attributes)) 1199 for ak, _ := range attributes { 1200 if ak == "id" { 1201 continue 1202 } 1203 1204 attrKeys = append(attrKeys, ak) 1205 } 1206 sort.Strings(attrKeys) 1207 1208 for _, ak := range attrKeys { 1209 av := attributes[ak] 1210 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) 1211 } 1212 1213 for idx, t := range rs.Deposed { 1214 taintStr := "" 1215 if t.Tainted { 1216 taintStr = " (tainted)" 1217 } 1218 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr)) 1219 } 1220 1221 if len(rs.Dependencies) > 0 { 1222 buf.WriteString(fmt.Sprintf("\n Dependencies:\n")) 1223 for _, dep := range rs.Dependencies { 1224 buf.WriteString(fmt.Sprintf(" %s\n", dep)) 1225 } 1226 } 1227 } 1228 1229 if len(m.Outputs) > 0 { 1230 buf.WriteString("\nOutputs:\n\n") 1231 1232 ks := make([]string, 0, len(m.Outputs)) 1233 for k, _ := range m.Outputs { 1234 ks = append(ks, k) 1235 } 1236 sort.Strings(ks) 1237 1238 for _, k := range ks { 1239 v := m.Outputs[k] 1240 switch vTyped := v.Value.(type) { 1241 case string: 1242 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1243 case []interface{}: 1244 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1245 case map[string]interface{}: 1246 var mapKeys []string 1247 for key, _ := range vTyped { 1248 mapKeys = append(mapKeys, key) 1249 } 1250 sort.Strings(mapKeys) 1251 1252 var mapBuf bytes.Buffer 1253 mapBuf.WriteString("{") 1254 for _, key := range mapKeys { 1255 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key])) 1256 } 1257 mapBuf.WriteString("}") 1258 1259 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String())) 1260 } 1261 } 1262 } 1263 1264 return buf.String() 1265 } 1266 1267 // ResourceStateKey is a structured representation of the key used for the 1268 // ModuleState.Resources mapping 1269 type ResourceStateKey struct { 1270 Name string 1271 Type string 1272 Mode config.ResourceMode 1273 Index int 1274 } 1275 1276 // Equal determines whether two ResourceStateKeys are the same 1277 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { 1278 if rsk == nil || other == nil { 1279 return false 1280 } 1281 if rsk.Mode != other.Mode { 1282 return false 1283 } 1284 if rsk.Type != other.Type { 1285 return false 1286 } 1287 if rsk.Name != other.Name { 1288 return false 1289 } 1290 if rsk.Index != other.Index { 1291 return false 1292 } 1293 return true 1294 } 1295 1296 func (rsk *ResourceStateKey) String() string { 1297 if rsk == nil { 1298 return "" 1299 } 1300 var prefix string 1301 switch rsk.Mode { 1302 case config.ManagedResourceMode: 1303 prefix = "" 1304 case config.DataResourceMode: 1305 prefix = "data." 1306 default: 1307 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) 1308 } 1309 if rsk.Index == -1 { 1310 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) 1311 } 1312 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) 1313 } 1314 1315 // ParseResourceStateKey accepts a key in the format used by 1316 // ModuleState.Resources and returns a resource name and resource index. In the 1317 // state, a resource has the format "type.name.index" or "type.name". In the 1318 // latter case, the index is returned as -1. 1319 func ParseResourceStateKey(k string) (*ResourceStateKey, error) { 1320 parts := strings.Split(k, ".") 1321 mode := config.ManagedResourceMode 1322 if len(parts) > 0 && parts[0] == "data" { 1323 mode = config.DataResourceMode 1324 // Don't need the constant "data" prefix for parsing 1325 // now that we've figured out the mode. 1326 parts = parts[1:] 1327 } 1328 if len(parts) < 2 || len(parts) > 3 { 1329 return nil, fmt.Errorf("Malformed resource state key: %s", k) 1330 } 1331 rsk := &ResourceStateKey{ 1332 Mode: mode, 1333 Type: parts[0], 1334 Name: parts[1], 1335 Index: -1, 1336 } 1337 if len(parts) == 3 { 1338 index, err := strconv.Atoi(parts[2]) 1339 if err != nil { 1340 return nil, fmt.Errorf("Malformed resource state key index: %s", k) 1341 } 1342 rsk.Index = index 1343 } 1344 return rsk, nil 1345 } 1346 1347 // ResourceState holds the state of a resource that is used so that 1348 // a provider can find and manage an existing resource as well as for 1349 // storing attributes that are used to populate variables of child 1350 // resources. 1351 // 1352 // Attributes has attributes about the created resource that are 1353 // queryable in interpolation: "${type.id.attr}" 1354 // 1355 // Extra is just extra data that a provider can return that we store 1356 // for later, but is not exposed in any way to the user. 1357 // 1358 type ResourceState struct { 1359 // This is filled in and managed by Terraform, and is the resource 1360 // type itself such as "mycloud_instance". If a resource provider sets 1361 // this value, it won't be persisted. 1362 Type string `json:"type"` 1363 1364 // Dependencies are a list of things that this resource relies on 1365 // existing to remain intact. For example: an AWS instance might 1366 // depend on a subnet (which itself might depend on a VPC, and so 1367 // on). 1368 // 1369 // Terraform uses this information to build valid destruction 1370 // orders and to warn the user if they're destroying a resource that 1371 // another resource depends on. 1372 // 1373 // Things can be put into this list that may not be managed by 1374 // Terraform. If Terraform doesn't find a matching ID in the 1375 // overall state, then it assumes it isn't managed and doesn't 1376 // worry about it. 1377 Dependencies []string `json:"depends_on"` 1378 1379 // Primary is the current active instance for this resource. 1380 // It can be replaced but only after a successful creation. 1381 // This is the instances on which providers will act. 1382 Primary *InstanceState `json:"primary"` 1383 1384 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 1385 // Primary is Deposed to get it out of the way for the replacement Primary to 1386 // be created by Apply. If the replacement Primary creates successfully, the 1387 // Deposed instance is cleaned up. 1388 // 1389 // If there were problems creating the replacement Primary, the Deposed 1390 // instance and the (now tainted) replacement Primary will be swapped so the 1391 // tainted replacement will be cleaned up instead. 1392 // 1393 // An instance will remain in the Deposed list until it is successfully 1394 // destroyed and purged. 1395 Deposed []*InstanceState `json:"deposed"` 1396 1397 // Provider is used when a resource is connected to a provider with an alias. 1398 // If this string is empty, the resource is connected to the default provider, 1399 // e.g. "aws_instance" goes with the "aws" provider. 1400 // If the resource block contained a "provider" key, that value will be set here. 1401 Provider string `json:"provider"` 1402 1403 mu sync.Mutex 1404 } 1405 1406 func (s *ResourceState) Lock() { s.mu.Lock() } 1407 func (s *ResourceState) Unlock() { s.mu.Unlock() } 1408 1409 // Equal tests whether two ResourceStates are equal. 1410 func (s *ResourceState) Equal(other *ResourceState) bool { 1411 s.Lock() 1412 defer s.Unlock() 1413 1414 if s.Type != other.Type { 1415 return false 1416 } 1417 1418 if s.Provider != other.Provider { 1419 return false 1420 } 1421 1422 // Dependencies must be equal 1423 sort.Strings(s.Dependencies) 1424 sort.Strings(other.Dependencies) 1425 if len(s.Dependencies) != len(other.Dependencies) { 1426 return false 1427 } 1428 for i, d := range s.Dependencies { 1429 if other.Dependencies[i] != d { 1430 return false 1431 } 1432 } 1433 1434 // States must be equal 1435 if !s.Primary.Equal(other.Primary) { 1436 return false 1437 } 1438 1439 return true 1440 } 1441 1442 // Taint marks a resource as tainted. 1443 func (s *ResourceState) Taint() { 1444 s.Lock() 1445 defer s.Unlock() 1446 1447 if s.Primary != nil { 1448 s.Primary.Tainted = true 1449 } 1450 } 1451 1452 // Untaint unmarks a resource as tainted. 1453 func (s *ResourceState) Untaint() { 1454 s.Lock() 1455 defer s.Unlock() 1456 1457 if s.Primary != nil { 1458 s.Primary.Tainted = false 1459 } 1460 } 1461 1462 func (s *ResourceState) init() { 1463 s.Lock() 1464 defer s.Unlock() 1465 1466 if s.Primary == nil { 1467 s.Primary = &InstanceState{} 1468 } 1469 s.Primary.init() 1470 1471 if s.Dependencies == nil { 1472 s.Dependencies = []string{} 1473 } 1474 1475 if s.Deposed == nil { 1476 s.Deposed = make([]*InstanceState, 0) 1477 } 1478 } 1479 1480 func (s *ResourceState) deepcopy() *ResourceState { 1481 copy, err := copystructure.Config{Lock: true}.Copy(s) 1482 if err != nil { 1483 panic(err) 1484 } 1485 1486 return copy.(*ResourceState) 1487 } 1488 1489 // prune is used to remove any instances that are no longer required 1490 func (s *ResourceState) prune() { 1491 s.Lock() 1492 defer s.Unlock() 1493 1494 n := len(s.Deposed) 1495 for i := 0; i < n; i++ { 1496 inst := s.Deposed[i] 1497 if inst == nil || inst.ID == "" { 1498 copy(s.Deposed[i:], s.Deposed[i+1:]) 1499 s.Deposed[n-1] = nil 1500 n-- 1501 i-- 1502 } 1503 } 1504 1505 s.Deposed = s.Deposed[:n] 1506 } 1507 1508 func (s *ResourceState) sort() { 1509 s.Lock() 1510 defer s.Unlock() 1511 1512 sort.Strings(s.Dependencies) 1513 } 1514 1515 func (s *ResourceState) String() string { 1516 s.Lock() 1517 defer s.Unlock() 1518 1519 var buf bytes.Buffer 1520 buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) 1521 return buf.String() 1522 } 1523 1524 // InstanceState is used to track the unique state information belonging 1525 // to a given instance. 1526 type InstanceState struct { 1527 // A unique ID for this resource. This is opaque to Terraform 1528 // and is only meant as a lookup mechanism for the providers. 1529 ID string `json:"id"` 1530 1531 // Attributes are basic information about the resource. Any keys here 1532 // are accessible in variable format within Terraform configurations: 1533 // ${resourcetype.name.attribute}. 1534 Attributes map[string]string `json:"attributes"` 1535 1536 // Ephemeral is used to store any state associated with this instance 1537 // that is necessary for the Terraform run to complete, but is not 1538 // persisted to a state file. 1539 Ephemeral EphemeralState `json:"-"` 1540 1541 // Meta is a simple K/V map that is persisted to the State but otherwise 1542 // ignored by Terraform core. It's meant to be used for accounting by 1543 // external client code. 1544 Meta map[string]string `json:"meta"` 1545 1546 // Tainted is used to mark a resource for recreation. 1547 Tainted bool `json:"tainted"` 1548 1549 mu sync.Mutex 1550 } 1551 1552 func (s *InstanceState) Lock() { s.mu.Lock() } 1553 func (s *InstanceState) Unlock() { s.mu.Unlock() } 1554 1555 func (s *InstanceState) init() { 1556 s.Lock() 1557 defer s.Unlock() 1558 1559 if s.Attributes == nil { 1560 s.Attributes = make(map[string]string) 1561 } 1562 if s.Meta == nil { 1563 s.Meta = make(map[string]string) 1564 } 1565 s.Ephemeral.init() 1566 } 1567 1568 // Copy all the Fields from another InstanceState 1569 func (s *InstanceState) Set(from *InstanceState) { 1570 s.Lock() 1571 defer s.Unlock() 1572 1573 from.Lock() 1574 defer from.Unlock() 1575 1576 s.ID = from.ID 1577 s.Attributes = from.Attributes 1578 s.Ephemeral = from.Ephemeral 1579 s.Meta = from.Meta 1580 s.Tainted = from.Tainted 1581 } 1582 1583 func (s *InstanceState) DeepCopy() *InstanceState { 1584 copy, err := copystructure.Config{Lock: true}.Copy(s) 1585 if err != nil { 1586 panic(err) 1587 } 1588 1589 return copy.(*InstanceState) 1590 } 1591 1592 func (s *InstanceState) Empty() bool { 1593 if s == nil { 1594 return true 1595 } 1596 s.Lock() 1597 defer s.Unlock() 1598 1599 return s.ID == "" 1600 } 1601 1602 func (s *InstanceState) Equal(other *InstanceState) bool { 1603 // Short circuit some nil checks 1604 if s == nil || other == nil { 1605 return s == other 1606 } 1607 s.Lock() 1608 defer s.Unlock() 1609 1610 // IDs must be equal 1611 if s.ID != other.ID { 1612 return false 1613 } 1614 1615 // Attributes must be equal 1616 if len(s.Attributes) != len(other.Attributes) { 1617 return false 1618 } 1619 for k, v := range s.Attributes { 1620 otherV, ok := other.Attributes[k] 1621 if !ok { 1622 return false 1623 } 1624 1625 if v != otherV { 1626 return false 1627 } 1628 } 1629 1630 // Meta must be equal 1631 if len(s.Meta) != len(other.Meta) { 1632 return false 1633 } 1634 for k, v := range s.Meta { 1635 otherV, ok := other.Meta[k] 1636 if !ok { 1637 return false 1638 } 1639 1640 if v != otherV { 1641 return false 1642 } 1643 } 1644 1645 if s.Tainted != other.Tainted { 1646 return false 1647 } 1648 1649 return true 1650 } 1651 1652 // MergeDiff takes a ResourceDiff and merges the attributes into 1653 // this resource state in order to generate a new state. This new 1654 // state can be used to provide updated attribute lookups for 1655 // variable interpolation. 1656 // 1657 // If the diff attribute requires computing the value, and hence 1658 // won't be available until apply, the value is replaced with the 1659 // computeID. 1660 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { 1661 result := s.DeepCopy() 1662 if result == nil { 1663 result = new(InstanceState) 1664 } 1665 result.init() 1666 1667 if s != nil { 1668 s.Lock() 1669 defer s.Unlock() 1670 for k, v := range s.Attributes { 1671 result.Attributes[k] = v 1672 } 1673 } 1674 if d != nil { 1675 for k, diff := range d.CopyAttributes() { 1676 if diff.NewRemoved { 1677 delete(result.Attributes, k) 1678 continue 1679 } 1680 if diff.NewComputed { 1681 result.Attributes[k] = config.UnknownVariableValue 1682 continue 1683 } 1684 1685 result.Attributes[k] = diff.New 1686 } 1687 } 1688 1689 // Remove any now empty array, maps or sets because a parent structure 1690 // won't include these entries in the count value. 1691 isCount := regexp.MustCompile(`\.[%#]$`).MatchString 1692 var deleted []string 1693 1694 for k, v := range result.Attributes { 1695 if isCount(k) && v == "0" { 1696 delete(result.Attributes, k) 1697 deleted = append(deleted, k) 1698 } 1699 } 1700 1701 for _, k := range deleted { 1702 // Sanity check for invalid structures. 1703 // If we removed the primary count key, there should have been no 1704 // other keys left with this prefix. 1705 1706 // this must have a "#" or "%" which we need to remove 1707 base := k[:len(k)-1] 1708 for k, _ := range result.Attributes { 1709 if strings.HasPrefix(k, base) { 1710 panic(fmt.Sprintf("empty structure %q has entry %q", base, k)) 1711 } 1712 } 1713 } 1714 1715 return result 1716 } 1717 1718 func (s *InstanceState) String() string { 1719 s.Lock() 1720 defer s.Unlock() 1721 1722 var buf bytes.Buffer 1723 1724 if s == nil || s.ID == "" { 1725 return "<not created>" 1726 } 1727 1728 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID)) 1729 1730 attributes := s.Attributes 1731 attrKeys := make([]string, 0, len(attributes)) 1732 for ak, _ := range attributes { 1733 if ak == "id" { 1734 continue 1735 } 1736 1737 attrKeys = append(attrKeys, ak) 1738 } 1739 sort.Strings(attrKeys) 1740 1741 for _, ak := range attrKeys { 1742 av := attributes[ak] 1743 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) 1744 } 1745 1746 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted)) 1747 1748 return buf.String() 1749 } 1750 1751 // EphemeralState is used for transient state that is only kept in-memory 1752 type EphemeralState struct { 1753 // ConnInfo is used for the providers to export information which is 1754 // used to connect to the resource for provisioning. For example, 1755 // this could contain SSH or WinRM credentials. 1756 ConnInfo map[string]string `json:"-"` 1757 1758 // Type is used to specify the resource type for this instance. This is only 1759 // required for import operations (as documented). If the documentation 1760 // doesn't state that you need to set this, then don't worry about 1761 // setting it. 1762 Type string `json:"-"` 1763 } 1764 1765 func (e *EphemeralState) init() { 1766 if e.ConnInfo == nil { 1767 e.ConnInfo = make(map[string]string) 1768 } 1769 } 1770 1771 func (e *EphemeralState) DeepCopy() *EphemeralState { 1772 copy, err := copystructure.Config{Lock: true}.Copy(e) 1773 if err != nil { 1774 panic(err) 1775 } 1776 1777 return copy.(*EphemeralState) 1778 } 1779 1780 type jsonStateVersionIdentifier struct { 1781 Version int `json:"version"` 1782 } 1783 1784 // Check if this is a V0 format - the magic bytes at the start of the file 1785 // should be "tfstate" if so. We no longer support upgrading this type of 1786 // state but return an error message explaining to a user how they can 1787 // upgrade via the 0.6.x series. 1788 func testForV0State(buf *bufio.Reader) error { 1789 start, err := buf.Peek(len("tfstate")) 1790 if err != nil { 1791 return fmt.Errorf("Failed to check for magic bytes: %v", err) 1792 } 1793 if string(start) == "tfstate" { 1794 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" + 1795 "format which was used prior to Terraform 0.3. Please upgrade\n" + 1796 "this state file using Terraform 0.6.16 prior to using it with\n" + 1797 "Terraform 0.7.") 1798 } 1799 1800 return nil 1801 } 1802 1803 // ReadState reads a state structure out of a reader in the format that 1804 // was written by WriteState. 1805 func ReadState(src io.Reader) (*State, error) { 1806 buf := bufio.NewReader(src) 1807 1808 if err := testForV0State(buf); err != nil { 1809 return nil, err 1810 } 1811 1812 // If we are JSON we buffer the whole thing in memory so we can read it twice. 1813 // This is suboptimal, but will work for now. 1814 jsonBytes, err := ioutil.ReadAll(buf) 1815 if err != nil { 1816 return nil, fmt.Errorf("Reading state file failed: %v", err) 1817 } 1818 1819 versionIdentifier := &jsonStateVersionIdentifier{} 1820 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil { 1821 return nil, fmt.Errorf("Decoding state file version failed: %v", err) 1822 } 1823 1824 var result *State 1825 switch versionIdentifier.Version { 1826 case 0: 1827 return nil, fmt.Errorf("State version 0 is not supported as JSON.") 1828 case 1: 1829 v1State, err := ReadStateV1(jsonBytes) 1830 if err != nil { 1831 return nil, err 1832 } 1833 1834 v2State, err := upgradeStateV1ToV2(v1State) 1835 if err != nil { 1836 return nil, err 1837 } 1838 1839 v3State, err := upgradeStateV2ToV3(v2State) 1840 if err != nil { 1841 return nil, err 1842 } 1843 1844 // increment the Serial whenever we upgrade state 1845 v3State.Serial++ 1846 result = v3State 1847 case 2: 1848 v2State, err := ReadStateV2(jsonBytes) 1849 if err != nil { 1850 return nil, err 1851 } 1852 v3State, err := upgradeStateV2ToV3(v2State) 1853 if err != nil { 1854 return nil, err 1855 } 1856 1857 v3State.Serial++ 1858 result = v3State 1859 case 3: 1860 v3State, err := ReadStateV3(jsonBytes) 1861 if err != nil { 1862 return nil, err 1863 } 1864 1865 result = v3State 1866 default: 1867 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1868 SemVersion.String(), versionIdentifier.Version) 1869 } 1870 1871 // If we reached this place we must have a result set 1872 if result == nil { 1873 panic("resulting state in load not set, assertion failed") 1874 } 1875 1876 // Prune the state when read it. Its possible to write unpruned states or 1877 // for a user to make a state unpruned (nil-ing a module state for example). 1878 result.prune() 1879 1880 // Validate the state file is valid 1881 if err := result.Validate(); err != nil { 1882 return nil, err 1883 } 1884 1885 return result, nil 1886 } 1887 1888 func ReadStateV1(jsonBytes []byte) (*stateV1, error) { 1889 v1State := &stateV1{} 1890 if err := json.Unmarshal(jsonBytes, v1State); err != nil { 1891 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1892 } 1893 1894 if v1State.Version != 1 { 1895 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+ 1896 "read %d, expected 1", v1State.Version) 1897 } 1898 1899 return v1State, nil 1900 } 1901 1902 func ReadStateV2(jsonBytes []byte) (*State, error) { 1903 state := &State{} 1904 if err := json.Unmarshal(jsonBytes, state); err != nil { 1905 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1906 } 1907 1908 // Check the version, this to ensure we don't read a future 1909 // version that we don't understand 1910 if state.Version > StateVersion { 1911 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1912 SemVersion.String(), state.Version) 1913 } 1914 1915 // Make sure the version is semantic 1916 if state.TFVersion != "" { 1917 if _, err := version.NewVersion(state.TFVersion); err != nil { 1918 return nil, fmt.Errorf( 1919 "State contains invalid version: %s\n\n"+ 1920 "Terraform validates the version format prior to writing it. This\n"+ 1921 "means that this is invalid of the state becoming corrupted through\n"+ 1922 "some external means. Please manually modify the Terraform version\n"+ 1923 "field to be a proper semantic version.", 1924 state.TFVersion) 1925 } 1926 } 1927 1928 // Sort it 1929 state.sort() 1930 1931 // catch any unitialized fields in the state 1932 state.init() 1933 1934 return state, nil 1935 } 1936 1937 func ReadStateV3(jsonBytes []byte) (*State, error) { 1938 state := &State{} 1939 if err := json.Unmarshal(jsonBytes, state); err != nil { 1940 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1941 } 1942 1943 // Check the version, this to ensure we don't read a future 1944 // version that we don't understand 1945 if state.Version > StateVersion { 1946 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1947 SemVersion.String(), state.Version) 1948 } 1949 1950 // Make sure the version is semantic 1951 if state.TFVersion != "" { 1952 if _, err := version.NewVersion(state.TFVersion); err != nil { 1953 return nil, fmt.Errorf( 1954 "State contains invalid version: %s\n\n"+ 1955 "Terraform validates the version format prior to writing it. This\n"+ 1956 "means that this is invalid of the state becoming corrupted through\n"+ 1957 "some external means. Please manually modify the Terraform version\n"+ 1958 "field to be a proper semantic version.", 1959 state.TFVersion) 1960 } 1961 } 1962 1963 // Sort it 1964 state.sort() 1965 1966 // catch any unitialized fields in the state 1967 state.init() 1968 1969 // Now we write the state back out to detect any changes in normaliztion. 1970 // If our state is now written out differently, bump the serial number to 1971 // prevent conflicts. 1972 var buf bytes.Buffer 1973 err := WriteState(state, &buf) 1974 if err != nil { 1975 return nil, err 1976 } 1977 1978 if !bytes.Equal(jsonBytes, buf.Bytes()) { 1979 log.Println("[INFO] state modified during read or write. incrementing serial number") 1980 state.Serial++ 1981 } 1982 1983 return state, nil 1984 } 1985 1986 // WriteState writes a state somewhere in a binary format. 1987 func WriteState(d *State, dst io.Writer) error { 1988 // Make sure it is sorted 1989 d.sort() 1990 1991 // make sure we have no uninitialized fields 1992 d.init() 1993 1994 // Ensure the version is set 1995 d.Version = StateVersion 1996 1997 // If the TFVersion is set, verify it. We used to just set the version 1998 // here, but this isn't safe since it changes the MD5 sum on some remote 1999 // state storage backends such as Atlas. We now leave it be if needed. 2000 if d.TFVersion != "" { 2001 if _, err := version.NewVersion(d.TFVersion); err != nil { 2002 return fmt.Errorf( 2003 "Error writing state, invalid version: %s\n\n"+ 2004 "The Terraform version when writing the state must be a semantic\n"+ 2005 "version.", 2006 d.TFVersion) 2007 } 2008 } 2009 2010 // Encode the data in a human-friendly way 2011 data, err := json.MarshalIndent(d, "", " ") 2012 if err != nil { 2013 return fmt.Errorf("Failed to encode state: %s", err) 2014 } 2015 2016 // We append a newline to the data because MarshalIndent doesn't 2017 data = append(data, '\n') 2018 2019 // Write the data out to the dst 2020 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil { 2021 return fmt.Errorf("Failed to write state: %v", err) 2022 } 2023 2024 return nil 2025 } 2026 2027 // moduleStateSort implements sort.Interface to sort module states 2028 type moduleStateSort []*ModuleState 2029 2030 func (s moduleStateSort) Len() int { 2031 return len(s) 2032 } 2033 2034 func (s moduleStateSort) Less(i, j int) bool { 2035 a := s[i] 2036 b := s[j] 2037 2038 // If either is nil, then the nil one is "less" than 2039 if a == nil || b == nil { 2040 return a == nil 2041 } 2042 2043 // If the lengths are different, then the shorter one always wins 2044 if len(a.Path) != len(b.Path) { 2045 return len(a.Path) < len(b.Path) 2046 } 2047 2048 // Otherwise, compare lexically 2049 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") 2050 } 2051 2052 func (s moduleStateSort) Swap(i, j int) { 2053 s[i], s[j] = s[j], s[i] 2054 } 2055 2056 const stateValidateErrMultiModule = ` 2057 Multiple modules with the same path: %s 2058 2059 This means that there are multiple entries in the "modules" field 2060 in your state file that point to the same module. This will cause Terraform 2061 to behave in unexpected and error prone ways and is invalid. Please back up 2062 and modify your state file manually to resolve this. 2063 `