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