github.com/bpineau/terraform@v0.8.0-rc1.0.20161126184705-a8886012d185/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 // We can't trust that state read from a file doesn't have nil/empty 648 // modules 649 s.prune() 650 651 for _, mod := range s.Modules { 652 mod.init() 653 } 654 655 if s.Remote != nil { 656 s.Remote.init() 657 } 658 659 } 660 661 func (s *State) EnsureHasLineage() { 662 s.Lock() 663 defer s.Unlock() 664 665 s.ensureHasLineage() 666 } 667 668 func (s *State) ensureHasLineage() { 669 if s.Lineage == "" { 670 s.Lineage = uuid.NewV4().String() 671 log.Printf("[DEBUG] New state was assigned lineage %q\n", s.Lineage) 672 } else { 673 log.Printf("[TRACE] Preserving existing state lineage %q\n", s.Lineage) 674 } 675 } 676 677 // AddModuleState insert this module state and override any existing ModuleState 678 func (s *State) AddModuleState(mod *ModuleState) { 679 mod.init() 680 s.Lock() 681 defer s.Unlock() 682 683 s.addModuleState(mod) 684 } 685 686 func (s *State) addModuleState(mod *ModuleState) { 687 for i, m := range s.Modules { 688 if reflect.DeepEqual(m.Path, mod.Path) { 689 s.Modules[i] = mod 690 return 691 } 692 } 693 694 s.Modules = append(s.Modules, mod) 695 s.sort() 696 } 697 698 // prune is used to remove any resources that are no longer required 699 func (s *State) prune() { 700 if s == nil { 701 return 702 } 703 704 // Filter out empty modules. 705 // A module is always assumed to have a path, and it's length isn't always 706 // bounds checked later on. Modules may be "emptied" during destroy, but we 707 // never want to store those in the state. 708 for i := 0; i < len(s.Modules); i++ { 709 if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 { 710 s.Modules = append(s.Modules[:i], s.Modules[i+1:]...) 711 i-- 712 } 713 } 714 715 for _, mod := range s.Modules { 716 mod.prune() 717 } 718 if s.Remote != nil && s.Remote.Empty() { 719 s.Remote = nil 720 } 721 } 722 723 // sort sorts the modules 724 func (s *State) sort() { 725 sort.Sort(moduleStateSort(s.Modules)) 726 727 // Allow modules to be sorted 728 for _, m := range s.Modules { 729 m.sort() 730 } 731 } 732 733 func (s *State) String() string { 734 if s == nil { 735 return "<nil>" 736 } 737 s.Lock() 738 defer s.Unlock() 739 740 var buf bytes.Buffer 741 for _, m := range s.Modules { 742 mStr := m.String() 743 744 // If we're the root module, we just write the output directly. 745 if reflect.DeepEqual(m.Path, rootModulePath) { 746 buf.WriteString(mStr + "\n") 747 continue 748 } 749 750 buf.WriteString(fmt.Sprintf("module.%s:\n", strings.Join(m.Path[1:], "."))) 751 752 s := bufio.NewScanner(strings.NewReader(mStr)) 753 for s.Scan() { 754 text := s.Text() 755 if text != "" { 756 text = " " + text 757 } 758 759 buf.WriteString(fmt.Sprintf("%s\n", text)) 760 } 761 } 762 763 return strings.TrimSpace(buf.String()) 764 } 765 766 // RemoteState is used to track the information about a remote 767 // state store that we push/pull state to. 768 type RemoteState struct { 769 // Type controls the client we use for the remote state 770 Type string `json:"type"` 771 772 // Config is used to store arbitrary configuration that 773 // is type specific 774 Config map[string]string `json:"config"` 775 776 mu sync.Mutex 777 } 778 779 func (s *RemoteState) Lock() { s.mu.Lock() } 780 func (s *RemoteState) Unlock() { s.mu.Unlock() } 781 782 func (r *RemoteState) init() { 783 r.Lock() 784 defer r.Unlock() 785 786 if r.Config == nil { 787 r.Config = make(map[string]string) 788 } 789 } 790 791 func (r *RemoteState) deepcopy() *RemoteState { 792 r.Lock() 793 defer r.Unlock() 794 795 confCopy := make(map[string]string, len(r.Config)) 796 for k, v := range r.Config { 797 confCopy[k] = v 798 } 799 return &RemoteState{ 800 Type: r.Type, 801 Config: confCopy, 802 } 803 } 804 805 func (r *RemoteState) Empty() bool { 806 if r == nil { 807 return true 808 } 809 r.Lock() 810 defer r.Unlock() 811 812 return r.Type == "" 813 } 814 815 func (r *RemoteState) Equals(other *RemoteState) bool { 816 r.Lock() 817 defer r.Unlock() 818 819 if r.Type != other.Type { 820 return false 821 } 822 if len(r.Config) != len(other.Config) { 823 return false 824 } 825 for k, v := range r.Config { 826 if other.Config[k] != v { 827 return false 828 } 829 } 830 return true 831 } 832 833 // OutputState is used to track the state relevant to a single output. 834 type OutputState struct { 835 // Sensitive describes whether the output is considered sensitive, 836 // which may lead to masking the value on screen in some cases. 837 Sensitive bool `json:"sensitive"` 838 // Type describes the structure of Value. Valid values are "string", 839 // "map" and "list" 840 Type string `json:"type"` 841 // Value contains the value of the output, in the structure described 842 // by the Type field. 843 Value interface{} `json:"value"` 844 845 mu sync.Mutex 846 } 847 848 func (s *OutputState) Lock() { s.mu.Lock() } 849 func (s *OutputState) Unlock() { s.mu.Unlock() } 850 851 func (s *OutputState) String() string { 852 return fmt.Sprintf("%#v", s.Value) 853 } 854 855 // Equal compares two OutputState structures for equality. nil values are 856 // considered equal. 857 func (s *OutputState) Equal(other *OutputState) bool { 858 if s == nil && other == nil { 859 return true 860 } 861 862 if s == nil || other == nil { 863 return false 864 } 865 s.Lock() 866 defer s.Unlock() 867 868 if s.Type != other.Type { 869 return false 870 } 871 872 if s.Sensitive != other.Sensitive { 873 return false 874 } 875 876 if !reflect.DeepEqual(s.Value, other.Value) { 877 return false 878 } 879 880 return true 881 } 882 883 func (s *OutputState) deepcopy() *OutputState { 884 if s == nil { 885 return nil 886 } 887 888 stateCopy, err := copystructure.Config{Lock: true}.Copy(s) 889 if err != nil { 890 panic(fmt.Errorf("Error copying output value: %s", err)) 891 } 892 893 return stateCopy.(*OutputState) 894 } 895 896 // ModuleState is used to track all the state relevant to a single 897 // module. Previous to Terraform 0.3, all state belonged to the "root" 898 // module. 899 type ModuleState struct { 900 // Path is the import path from the root module. Modules imports are 901 // always disjoint, so the path represents amodule tree 902 Path []string `json:"path"` 903 904 // Outputs declared by the module and maintained for each module 905 // even though only the root module technically needs to be kept. 906 // This allows operators to inspect values at the boundaries. 907 Outputs map[string]*OutputState `json:"outputs"` 908 909 // Resources is a mapping of the logically named resource to 910 // the state of the resource. Each resource may actually have 911 // N instances underneath, although a user only needs to think 912 // about the 1:1 case. 913 Resources map[string]*ResourceState `json:"resources"` 914 915 // Dependencies are a list of things that this module relies on 916 // existing to remain intact. For example: an module may depend 917 // on a VPC ID given by an aws_vpc resource. 918 // 919 // Terraform uses this information to build valid destruction 920 // orders and to warn the user if they're destroying a module that 921 // another resource depends on. 922 // 923 // Things can be put into this list that may not be managed by 924 // Terraform. If Terraform doesn't find a matching ID in the 925 // overall state, then it assumes it isn't managed and doesn't 926 // worry about it. 927 Dependencies []string `json:"depends_on"` 928 929 mu sync.Mutex 930 } 931 932 func (s *ModuleState) Lock() { s.mu.Lock() } 933 func (s *ModuleState) Unlock() { s.mu.Unlock() } 934 935 // Equal tests whether one module state is equal to another. 936 func (m *ModuleState) Equal(other *ModuleState) bool { 937 m.Lock() 938 defer m.Unlock() 939 940 // Paths must be equal 941 if !reflect.DeepEqual(m.Path, other.Path) { 942 return false 943 } 944 945 // Outputs must be equal 946 if len(m.Outputs) != len(other.Outputs) { 947 return false 948 } 949 for k, v := range m.Outputs { 950 if !other.Outputs[k].Equal(v) { 951 return false 952 } 953 } 954 955 // Dependencies must be equal. This sorts these in place but 956 // this shouldn't cause any problems. 957 sort.Strings(m.Dependencies) 958 sort.Strings(other.Dependencies) 959 if len(m.Dependencies) != len(other.Dependencies) { 960 return false 961 } 962 for i, d := range m.Dependencies { 963 if other.Dependencies[i] != d { 964 return false 965 } 966 } 967 968 // Resources must be equal 969 if len(m.Resources) != len(other.Resources) { 970 return false 971 } 972 for k, r := range m.Resources { 973 otherR, ok := other.Resources[k] 974 if !ok { 975 return false 976 } 977 978 if !r.Equal(otherR) { 979 return false 980 } 981 } 982 983 return true 984 } 985 986 // IsRoot says whether or not this module diff is for the root module. 987 func (m *ModuleState) IsRoot() bool { 988 m.Lock() 989 defer m.Unlock() 990 return reflect.DeepEqual(m.Path, rootModulePath) 991 } 992 993 // IsDescendent returns true if other is a descendent of this module. 994 func (m *ModuleState) IsDescendent(other *ModuleState) bool { 995 m.Lock() 996 defer m.Unlock() 997 998 i := len(m.Path) 999 return len(other.Path) > i && reflect.DeepEqual(other.Path[:i], m.Path) 1000 } 1001 1002 // Orphans returns a list of keys of resources that are in the State 1003 // but aren't present in the configuration itself. Hence, these keys 1004 // represent the state of resources that are orphans. 1005 func (m *ModuleState) Orphans(c *config.Config) []string { 1006 m.Lock() 1007 defer m.Unlock() 1008 1009 keys := make(map[string]struct{}) 1010 for k, _ := range m.Resources { 1011 keys[k] = struct{}{} 1012 } 1013 1014 if c != nil { 1015 for _, r := range c.Resources { 1016 delete(keys, r.Id()) 1017 1018 for k, _ := range keys { 1019 if strings.HasPrefix(k, r.Id()+".") { 1020 delete(keys, k) 1021 } 1022 } 1023 } 1024 } 1025 1026 result := make([]string, 0, len(keys)) 1027 for k, _ := range keys { 1028 result = append(result, k) 1029 } 1030 1031 return result 1032 } 1033 1034 // View returns a view with the given resource prefix. 1035 func (m *ModuleState) View(id string) *ModuleState { 1036 if m == nil { 1037 return m 1038 } 1039 1040 r := m.deepcopy() 1041 for k, _ := range r.Resources { 1042 if id == k || strings.HasPrefix(k, id+".") { 1043 continue 1044 } 1045 1046 delete(r.Resources, k) 1047 } 1048 1049 return r 1050 } 1051 1052 func (m *ModuleState) init() { 1053 m.Lock() 1054 defer m.Unlock() 1055 1056 if m.Path == nil { 1057 m.Path = []string{} 1058 } 1059 if m.Outputs == nil { 1060 m.Outputs = make(map[string]*OutputState) 1061 } 1062 if m.Resources == nil { 1063 m.Resources = make(map[string]*ResourceState) 1064 } 1065 1066 if m.Dependencies == nil { 1067 m.Dependencies = make([]string, 0) 1068 } 1069 1070 for _, rs := range m.Resources { 1071 rs.init() 1072 } 1073 } 1074 1075 func (m *ModuleState) deepcopy() *ModuleState { 1076 if m == nil { 1077 return nil 1078 } 1079 1080 stateCopy, err := copystructure.Config{Lock: true}.Copy(m) 1081 if err != nil { 1082 panic(err) 1083 } 1084 1085 return stateCopy.(*ModuleState) 1086 } 1087 1088 // prune is used to remove any resources that are no longer required 1089 func (m *ModuleState) prune() { 1090 m.Lock() 1091 defer m.Unlock() 1092 1093 for k, v := range m.Resources { 1094 if v == nil || (v.Primary == nil || v.Primary.ID == "") && len(v.Deposed) == 0 { 1095 delete(m.Resources, k) 1096 continue 1097 } 1098 1099 v.prune() 1100 } 1101 1102 for k, v := range m.Outputs { 1103 if v.Value == config.UnknownVariableValue { 1104 delete(m.Outputs, k) 1105 } 1106 } 1107 } 1108 1109 func (m *ModuleState) sort() { 1110 for _, v := range m.Resources { 1111 v.sort() 1112 } 1113 } 1114 1115 func (m *ModuleState) String() string { 1116 m.Lock() 1117 defer m.Unlock() 1118 1119 var buf bytes.Buffer 1120 1121 if len(m.Resources) == 0 { 1122 buf.WriteString("<no state>") 1123 } 1124 1125 names := make([]string, 0, len(m.Resources)) 1126 for name, _ := range m.Resources { 1127 names = append(names, name) 1128 } 1129 sort.Strings(names) 1130 1131 for _, k := range names { 1132 rs := m.Resources[k] 1133 var id string 1134 if rs.Primary != nil { 1135 id = rs.Primary.ID 1136 } 1137 if id == "" { 1138 id = "<not created>" 1139 } 1140 1141 taintStr := "" 1142 if rs.Primary.Tainted { 1143 taintStr = " (tainted)" 1144 } 1145 1146 deposedStr := "" 1147 if len(rs.Deposed) > 0 { 1148 deposedStr = fmt.Sprintf(" (%d deposed)", len(rs.Deposed)) 1149 } 1150 1151 buf.WriteString(fmt.Sprintf("%s:%s%s\n", k, taintStr, deposedStr)) 1152 buf.WriteString(fmt.Sprintf(" ID = %s\n", id)) 1153 if rs.Provider != "" { 1154 buf.WriteString(fmt.Sprintf(" provider = %s\n", rs.Provider)) 1155 } 1156 1157 var attributes map[string]string 1158 if rs.Primary != nil { 1159 attributes = rs.Primary.Attributes 1160 } 1161 attrKeys := make([]string, 0, len(attributes)) 1162 for ak, _ := range attributes { 1163 if ak == "id" { 1164 continue 1165 } 1166 1167 attrKeys = append(attrKeys, ak) 1168 } 1169 sort.Strings(attrKeys) 1170 1171 for _, ak := range attrKeys { 1172 av := attributes[ak] 1173 buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av)) 1174 } 1175 1176 for idx, t := range rs.Deposed { 1177 taintStr := "" 1178 if t.Tainted { 1179 taintStr = " (tainted)" 1180 } 1181 buf.WriteString(fmt.Sprintf(" Deposed ID %d = %s%s\n", idx+1, t.ID, taintStr)) 1182 } 1183 1184 if len(rs.Dependencies) > 0 { 1185 buf.WriteString(fmt.Sprintf("\n Dependencies:\n")) 1186 for _, dep := range rs.Dependencies { 1187 buf.WriteString(fmt.Sprintf(" %s\n", dep)) 1188 } 1189 } 1190 } 1191 1192 if len(m.Outputs) > 0 { 1193 buf.WriteString("\nOutputs:\n\n") 1194 1195 ks := make([]string, 0, len(m.Outputs)) 1196 for k, _ := range m.Outputs { 1197 ks = append(ks, k) 1198 } 1199 sort.Strings(ks) 1200 1201 for _, k := range ks { 1202 v := m.Outputs[k] 1203 switch vTyped := v.Value.(type) { 1204 case string: 1205 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1206 case []interface{}: 1207 buf.WriteString(fmt.Sprintf("%s = %s\n", k, vTyped)) 1208 case map[string]interface{}: 1209 var mapKeys []string 1210 for key, _ := range vTyped { 1211 mapKeys = append(mapKeys, key) 1212 } 1213 sort.Strings(mapKeys) 1214 1215 var mapBuf bytes.Buffer 1216 mapBuf.WriteString("{") 1217 for _, key := range mapKeys { 1218 mapBuf.WriteString(fmt.Sprintf("%s:%s ", key, vTyped[key])) 1219 } 1220 mapBuf.WriteString("}") 1221 1222 buf.WriteString(fmt.Sprintf("%s = %s\n", k, mapBuf.String())) 1223 } 1224 } 1225 } 1226 1227 return buf.String() 1228 } 1229 1230 // ResourceStateKey is a structured representation of the key used for the 1231 // ModuleState.Resources mapping 1232 type ResourceStateKey struct { 1233 Name string 1234 Type string 1235 Mode config.ResourceMode 1236 Index int 1237 } 1238 1239 // Equal determines whether two ResourceStateKeys are the same 1240 func (rsk *ResourceStateKey) Equal(other *ResourceStateKey) bool { 1241 if rsk == nil || other == nil { 1242 return false 1243 } 1244 if rsk.Mode != other.Mode { 1245 return false 1246 } 1247 if rsk.Type != other.Type { 1248 return false 1249 } 1250 if rsk.Name != other.Name { 1251 return false 1252 } 1253 if rsk.Index != other.Index { 1254 return false 1255 } 1256 return true 1257 } 1258 1259 func (rsk *ResourceStateKey) String() string { 1260 if rsk == nil { 1261 return "" 1262 } 1263 var prefix string 1264 switch rsk.Mode { 1265 case config.ManagedResourceMode: 1266 prefix = "" 1267 case config.DataResourceMode: 1268 prefix = "data." 1269 default: 1270 panic(fmt.Errorf("unknown resource mode %s", rsk.Mode)) 1271 } 1272 if rsk.Index == -1 { 1273 return fmt.Sprintf("%s%s.%s", prefix, rsk.Type, rsk.Name) 1274 } 1275 return fmt.Sprintf("%s%s.%s.%d", prefix, rsk.Type, rsk.Name, rsk.Index) 1276 } 1277 1278 // ParseResourceStateKey accepts a key in the format used by 1279 // ModuleState.Resources and returns a resource name and resource index. In the 1280 // state, a resource has the format "type.name.index" or "type.name". In the 1281 // latter case, the index is returned as -1. 1282 func ParseResourceStateKey(k string) (*ResourceStateKey, error) { 1283 parts := strings.Split(k, ".") 1284 mode := config.ManagedResourceMode 1285 if len(parts) > 0 && parts[0] == "data" { 1286 mode = config.DataResourceMode 1287 // Don't need the constant "data" prefix for parsing 1288 // now that we've figured out the mode. 1289 parts = parts[1:] 1290 } 1291 if len(parts) < 2 || len(parts) > 3 { 1292 return nil, fmt.Errorf("Malformed resource state key: %s", k) 1293 } 1294 rsk := &ResourceStateKey{ 1295 Mode: mode, 1296 Type: parts[0], 1297 Name: parts[1], 1298 Index: -1, 1299 } 1300 if len(parts) == 3 { 1301 index, err := strconv.Atoi(parts[2]) 1302 if err != nil { 1303 return nil, fmt.Errorf("Malformed resource state key index: %s", k) 1304 } 1305 rsk.Index = index 1306 } 1307 return rsk, nil 1308 } 1309 1310 // ResourceState holds the state of a resource that is used so that 1311 // a provider can find and manage an existing resource as well as for 1312 // storing attributes that are used to populate variables of child 1313 // resources. 1314 // 1315 // Attributes has attributes about the created resource that are 1316 // queryable in interpolation: "${type.id.attr}" 1317 // 1318 // Extra is just extra data that a provider can return that we store 1319 // for later, but is not exposed in any way to the user. 1320 // 1321 type ResourceState struct { 1322 // This is filled in and managed by Terraform, and is the resource 1323 // type itself such as "mycloud_instance". If a resource provider sets 1324 // this value, it won't be persisted. 1325 Type string `json:"type"` 1326 1327 // Dependencies are a list of things that this resource relies on 1328 // existing to remain intact. For example: an AWS instance might 1329 // depend on a subnet (which itself might depend on a VPC, and so 1330 // on). 1331 // 1332 // Terraform uses this information to build valid destruction 1333 // orders and to warn the user if they're destroying a resource that 1334 // another resource depends on. 1335 // 1336 // Things can be put into this list that may not be managed by 1337 // Terraform. If Terraform doesn't find a matching ID in the 1338 // overall state, then it assumes it isn't managed and doesn't 1339 // worry about it. 1340 Dependencies []string `json:"depends_on"` 1341 1342 // Primary is the current active instance for this resource. 1343 // It can be replaced but only after a successful creation. 1344 // This is the instances on which providers will act. 1345 Primary *InstanceState `json:"primary"` 1346 1347 // Deposed is used in the mechanics of CreateBeforeDestroy: the existing 1348 // Primary is Deposed to get it out of the way for the replacement Primary to 1349 // be created by Apply. If the replacement Primary creates successfully, the 1350 // Deposed instance is cleaned up. 1351 // 1352 // If there were problems creating the replacement Primary, the Deposed 1353 // instance and the (now tainted) replacement Primary will be swapped so the 1354 // tainted replacement will be cleaned up instead. 1355 // 1356 // An instance will remain in the Deposed list until it is successfully 1357 // destroyed and purged. 1358 Deposed []*InstanceState `json:"deposed"` 1359 1360 // Provider is used when a resource is connected to a provider with an alias. 1361 // If this string is empty, the resource is connected to the default provider, 1362 // e.g. "aws_instance" goes with the "aws" provider. 1363 // If the resource block contained a "provider" key, that value will be set here. 1364 Provider string `json:"provider"` 1365 1366 mu sync.Mutex 1367 } 1368 1369 func (s *ResourceState) Lock() { s.mu.Lock() } 1370 func (s *ResourceState) Unlock() { s.mu.Unlock() } 1371 1372 // Equal tests whether two ResourceStates are equal. 1373 func (s *ResourceState) Equal(other *ResourceState) bool { 1374 s.Lock() 1375 defer s.Unlock() 1376 1377 if s.Type != other.Type { 1378 return false 1379 } 1380 1381 if s.Provider != other.Provider { 1382 return false 1383 } 1384 1385 // Dependencies must be equal 1386 sort.Strings(s.Dependencies) 1387 sort.Strings(other.Dependencies) 1388 if len(s.Dependencies) != len(other.Dependencies) { 1389 return false 1390 } 1391 for i, d := range s.Dependencies { 1392 if other.Dependencies[i] != d { 1393 return false 1394 } 1395 } 1396 1397 // States must be equal 1398 if !s.Primary.Equal(other.Primary) { 1399 return false 1400 } 1401 1402 return true 1403 } 1404 1405 // Taint marks a resource as tainted. 1406 func (s *ResourceState) Taint() { 1407 s.Lock() 1408 defer s.Unlock() 1409 1410 if s.Primary != nil { 1411 s.Primary.Tainted = true 1412 } 1413 } 1414 1415 // Untaint unmarks a resource as tainted. 1416 func (s *ResourceState) Untaint() { 1417 s.Lock() 1418 defer s.Unlock() 1419 1420 if s.Primary != nil { 1421 s.Primary.Tainted = false 1422 } 1423 } 1424 1425 func (s *ResourceState) init() { 1426 s.Lock() 1427 defer s.Unlock() 1428 1429 if s.Primary == nil { 1430 s.Primary = &InstanceState{} 1431 } 1432 s.Primary.init() 1433 1434 if s.Dependencies == nil { 1435 s.Dependencies = []string{} 1436 } 1437 1438 if s.Deposed == nil { 1439 s.Deposed = make([]*InstanceState, 0) 1440 } 1441 } 1442 1443 func (s *ResourceState) deepcopy() *ResourceState { 1444 copy, err := copystructure.Config{Lock: true}.Copy(s) 1445 if err != nil { 1446 panic(err) 1447 } 1448 1449 return copy.(*ResourceState) 1450 } 1451 1452 // prune is used to remove any instances that are no longer required 1453 func (s *ResourceState) prune() { 1454 s.Lock() 1455 defer s.Unlock() 1456 1457 n := len(s.Deposed) 1458 for i := 0; i < n; i++ { 1459 inst := s.Deposed[i] 1460 if inst == nil || inst.ID == "" { 1461 copy(s.Deposed[i:], s.Deposed[i+1:]) 1462 s.Deposed[n-1] = nil 1463 n-- 1464 i-- 1465 } 1466 } 1467 1468 s.Deposed = s.Deposed[:n] 1469 } 1470 1471 func (s *ResourceState) sort() { 1472 s.Lock() 1473 defer s.Unlock() 1474 1475 sort.Strings(s.Dependencies) 1476 } 1477 1478 func (s *ResourceState) String() string { 1479 s.Lock() 1480 defer s.Unlock() 1481 1482 var buf bytes.Buffer 1483 buf.WriteString(fmt.Sprintf("Type = %s", s.Type)) 1484 return buf.String() 1485 } 1486 1487 // InstanceState is used to track the unique state information belonging 1488 // to a given instance. 1489 type InstanceState struct { 1490 // A unique ID for this resource. This is opaque to Terraform 1491 // and is only meant as a lookup mechanism for the providers. 1492 ID string `json:"id"` 1493 1494 // Attributes are basic information about the resource. Any keys here 1495 // are accessible in variable format within Terraform configurations: 1496 // ${resourcetype.name.attribute}. 1497 Attributes map[string]string `json:"attributes"` 1498 1499 // Ephemeral is used to store any state associated with this instance 1500 // that is necessary for the Terraform run to complete, but is not 1501 // persisted to a state file. 1502 Ephemeral EphemeralState `json:"-"` 1503 1504 // Meta is a simple K/V map that is persisted to the State but otherwise 1505 // ignored by Terraform core. It's meant to be used for accounting by 1506 // external client code. 1507 Meta map[string]string `json:"meta"` 1508 1509 // Tainted is used to mark a resource for recreation. 1510 Tainted bool `json:"tainted"` 1511 1512 mu sync.Mutex 1513 } 1514 1515 func (s *InstanceState) Lock() { s.mu.Lock() } 1516 func (s *InstanceState) Unlock() { s.mu.Unlock() } 1517 1518 func (s *InstanceState) init() { 1519 s.Lock() 1520 defer s.Unlock() 1521 1522 if s.Attributes == nil { 1523 s.Attributes = make(map[string]string) 1524 } 1525 if s.Meta == nil { 1526 s.Meta = make(map[string]string) 1527 } 1528 s.Ephemeral.init() 1529 } 1530 1531 // Copy all the Fields from another InstanceState 1532 func (s *InstanceState) Set(from *InstanceState) { 1533 s.Lock() 1534 defer s.Unlock() 1535 1536 from.Lock() 1537 defer from.Unlock() 1538 1539 s.ID = from.ID 1540 s.Attributes = from.Attributes 1541 s.Ephemeral = from.Ephemeral 1542 s.Meta = from.Meta 1543 s.Tainted = from.Tainted 1544 } 1545 1546 func (s *InstanceState) DeepCopy() *InstanceState { 1547 copy, err := copystructure.Config{Lock: true}.Copy(s) 1548 if err != nil { 1549 panic(err) 1550 } 1551 1552 return copy.(*InstanceState) 1553 } 1554 1555 func (s *InstanceState) Empty() bool { 1556 if s == nil { 1557 return true 1558 } 1559 s.Lock() 1560 defer s.Unlock() 1561 1562 return s.ID == "" 1563 } 1564 1565 func (s *InstanceState) Equal(other *InstanceState) bool { 1566 // Short circuit some nil checks 1567 if s == nil || other == nil { 1568 return s == other 1569 } 1570 s.Lock() 1571 defer s.Unlock() 1572 1573 // IDs must be equal 1574 if s.ID != other.ID { 1575 return false 1576 } 1577 1578 // Attributes must be equal 1579 if len(s.Attributes) != len(other.Attributes) { 1580 return false 1581 } 1582 for k, v := range s.Attributes { 1583 otherV, ok := other.Attributes[k] 1584 if !ok { 1585 return false 1586 } 1587 1588 if v != otherV { 1589 return false 1590 } 1591 } 1592 1593 // Meta must be equal 1594 if len(s.Meta) != len(other.Meta) { 1595 return false 1596 } 1597 for k, v := range s.Meta { 1598 otherV, ok := other.Meta[k] 1599 if !ok { 1600 return false 1601 } 1602 1603 if v != otherV { 1604 return false 1605 } 1606 } 1607 1608 if s.Tainted != other.Tainted { 1609 return false 1610 } 1611 1612 return true 1613 } 1614 1615 // MergeDiff takes a ResourceDiff and merges the attributes into 1616 // this resource state in order to generate a new state. This new 1617 // state can be used to provide updated attribute lookups for 1618 // variable interpolation. 1619 // 1620 // If the diff attribute requires computing the value, and hence 1621 // won't be available until apply, the value is replaced with the 1622 // computeID. 1623 func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState { 1624 result := s.DeepCopy() 1625 if result == nil { 1626 result = new(InstanceState) 1627 } 1628 result.init() 1629 1630 if s != nil { 1631 s.Lock() 1632 defer s.Unlock() 1633 for k, v := range s.Attributes { 1634 result.Attributes[k] = v 1635 } 1636 } 1637 if d != nil { 1638 for k, diff := range d.CopyAttributes() { 1639 if diff.NewRemoved { 1640 delete(result.Attributes, k) 1641 continue 1642 } 1643 if diff.NewComputed { 1644 result.Attributes[k] = config.UnknownVariableValue 1645 continue 1646 } 1647 1648 result.Attributes[k] = diff.New 1649 } 1650 } 1651 1652 return result 1653 } 1654 1655 func (s *InstanceState) String() string { 1656 s.Lock() 1657 defer s.Unlock() 1658 1659 var buf bytes.Buffer 1660 1661 if s == nil || s.ID == "" { 1662 return "<not created>" 1663 } 1664 1665 buf.WriteString(fmt.Sprintf("ID = %s\n", s.ID)) 1666 1667 attributes := s.Attributes 1668 attrKeys := make([]string, 0, len(attributes)) 1669 for ak, _ := range attributes { 1670 if ak == "id" { 1671 continue 1672 } 1673 1674 attrKeys = append(attrKeys, ak) 1675 } 1676 sort.Strings(attrKeys) 1677 1678 for _, ak := range attrKeys { 1679 av := attributes[ak] 1680 buf.WriteString(fmt.Sprintf("%s = %s\n", ak, av)) 1681 } 1682 1683 buf.WriteString(fmt.Sprintf("Tainted = %t\n", s.Tainted)) 1684 1685 return buf.String() 1686 } 1687 1688 // EphemeralState is used for transient state that is only kept in-memory 1689 type EphemeralState struct { 1690 // ConnInfo is used for the providers to export information which is 1691 // used to connect to the resource for provisioning. For example, 1692 // this could contain SSH or WinRM credentials. 1693 ConnInfo map[string]string `json:"-"` 1694 1695 // Type is used to specify the resource type for this instance. This is only 1696 // required for import operations (as documented). If the documentation 1697 // doesn't state that you need to set this, then don't worry about 1698 // setting it. 1699 Type string `json:"-"` 1700 } 1701 1702 func (e *EphemeralState) init() { 1703 if e.ConnInfo == nil { 1704 e.ConnInfo = make(map[string]string) 1705 } 1706 } 1707 1708 func (e *EphemeralState) DeepCopy() *EphemeralState { 1709 copy, err := copystructure.Config{Lock: true}.Copy(e) 1710 if err != nil { 1711 panic(err) 1712 } 1713 1714 return copy.(*EphemeralState) 1715 } 1716 1717 type jsonStateVersionIdentifier struct { 1718 Version int `json:"version"` 1719 } 1720 1721 // Check if this is a V0 format - the magic bytes at the start of the file 1722 // should be "tfstate" if so. We no longer support upgrading this type of 1723 // state but return an error message explaining to a user how they can 1724 // upgrade via the 0.6.x series. 1725 func testForV0State(buf *bufio.Reader) error { 1726 start, err := buf.Peek(len("tfstate")) 1727 if err != nil { 1728 return fmt.Errorf("Failed to check for magic bytes: %v", err) 1729 } 1730 if string(start) == "tfstate" { 1731 return fmt.Errorf("Terraform 0.7 no longer supports upgrading the binary state\n" + 1732 "format which was used prior to Terraform 0.3. Please upgrade\n" + 1733 "this state file using Terraform 0.6.16 prior to using it with\n" + 1734 "Terraform 0.7.") 1735 } 1736 1737 return nil 1738 } 1739 1740 // ReadState reads a state structure out of a reader in the format that 1741 // was written by WriteState. 1742 func ReadState(src io.Reader) (*State, error) { 1743 buf := bufio.NewReader(src) 1744 1745 if err := testForV0State(buf); err != nil { 1746 return nil, err 1747 } 1748 1749 // If we are JSON we buffer the whole thing in memory so we can read it twice. 1750 // This is suboptimal, but will work for now. 1751 jsonBytes, err := ioutil.ReadAll(buf) 1752 if err != nil { 1753 return nil, fmt.Errorf("Reading state file failed: %v", err) 1754 } 1755 1756 versionIdentifier := &jsonStateVersionIdentifier{} 1757 if err := json.Unmarshal(jsonBytes, versionIdentifier); err != nil { 1758 return nil, fmt.Errorf("Decoding state file version failed: %v", err) 1759 } 1760 1761 var result *State 1762 switch versionIdentifier.Version { 1763 case 0: 1764 return nil, fmt.Errorf("State version 0 is not supported as JSON.") 1765 case 1: 1766 v1State, err := ReadStateV1(jsonBytes) 1767 if err != nil { 1768 return nil, err 1769 } 1770 1771 v2State, err := upgradeStateV1ToV2(v1State) 1772 if err != nil { 1773 return nil, err 1774 } 1775 1776 v3State, err := upgradeStateV2ToV3(v2State) 1777 if err != nil { 1778 return nil, err 1779 } 1780 1781 // increment the Serial whenever we upgrade state 1782 v3State.Serial++ 1783 result = v3State 1784 case 2: 1785 v2State, err := ReadStateV2(jsonBytes) 1786 if err != nil { 1787 return nil, err 1788 } 1789 v3State, err := upgradeStateV2ToV3(v2State) 1790 if err != nil { 1791 return nil, err 1792 } 1793 1794 v3State.Serial++ 1795 result = v3State 1796 case 3: 1797 v3State, err := ReadStateV3(jsonBytes) 1798 if err != nil { 1799 return nil, err 1800 } 1801 1802 result = v3State 1803 default: 1804 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1805 SemVersion.String(), versionIdentifier.Version) 1806 } 1807 1808 // If we reached this place we must have a result set 1809 if result == nil { 1810 panic("resulting state in load not set, assertion failed") 1811 } 1812 1813 // Validate the state file is valid 1814 if err := result.Validate(); err != nil { 1815 return nil, err 1816 } 1817 1818 return result, nil 1819 } 1820 1821 func ReadStateV1(jsonBytes []byte) (*stateV1, error) { 1822 v1State := &stateV1{} 1823 if err := json.Unmarshal(jsonBytes, v1State); err != nil { 1824 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1825 } 1826 1827 if v1State.Version != 1 { 1828 return nil, fmt.Errorf("Decoded state version did not match the decoder selection: "+ 1829 "read %d, expected 1", v1State.Version) 1830 } 1831 1832 return v1State, nil 1833 } 1834 1835 func ReadStateV2(jsonBytes []byte) (*State, error) { 1836 state := &State{} 1837 if err := json.Unmarshal(jsonBytes, state); err != nil { 1838 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1839 } 1840 1841 // Check the version, this to ensure we don't read a future 1842 // version that we don't understand 1843 if state.Version > StateVersion { 1844 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1845 SemVersion.String(), state.Version) 1846 } 1847 1848 // Make sure the version is semantic 1849 if state.TFVersion != "" { 1850 if _, err := version.NewVersion(state.TFVersion); err != nil { 1851 return nil, fmt.Errorf( 1852 "State contains invalid version: %s\n\n"+ 1853 "Terraform validates the version format prior to writing it. This\n"+ 1854 "means that this is invalid of the state becoming corrupted through\n"+ 1855 "some external means. Please manually modify the Terraform version\n"+ 1856 "field to be a proper semantic version.", 1857 state.TFVersion) 1858 } 1859 } 1860 1861 // Sort it 1862 state.sort() 1863 1864 // catch any unitialized fields in the state 1865 state.init() 1866 1867 return state, nil 1868 } 1869 1870 func ReadStateV3(jsonBytes []byte) (*State, error) { 1871 state := &State{} 1872 if err := json.Unmarshal(jsonBytes, state); err != nil { 1873 return nil, fmt.Errorf("Decoding state file failed: %v", err) 1874 } 1875 1876 // Check the version, this to ensure we don't read a future 1877 // version that we don't understand 1878 if state.Version > StateVersion { 1879 return nil, fmt.Errorf("Terraform %s does not support state version %d, please update.", 1880 SemVersion.String(), state.Version) 1881 } 1882 1883 // Make sure the version is semantic 1884 if state.TFVersion != "" { 1885 if _, err := version.NewVersion(state.TFVersion); err != nil { 1886 return nil, fmt.Errorf( 1887 "State contains invalid version: %s\n\n"+ 1888 "Terraform validates the version format prior to writing it. This\n"+ 1889 "means that this is invalid of the state becoming corrupted through\n"+ 1890 "some external means. Please manually modify the Terraform version\n"+ 1891 "field to be a proper semantic version.", 1892 state.TFVersion) 1893 } 1894 } 1895 1896 // Sort it 1897 state.sort() 1898 1899 // catch any unitialized fields in the state 1900 state.init() 1901 1902 // Now we write the state back out to detect any changes in normaliztion. 1903 // If our state is now written out differently, bump the serial number to 1904 // prevent conflicts. 1905 var buf bytes.Buffer 1906 err := WriteState(state, &buf) 1907 if err != nil { 1908 return nil, err 1909 } 1910 1911 if !bytes.Equal(jsonBytes, buf.Bytes()) { 1912 log.Println("[INFO] state modified during read or write. incrementing serial number") 1913 state.Serial++ 1914 } 1915 1916 return state, nil 1917 } 1918 1919 // WriteState writes a state somewhere in a binary format. 1920 func WriteState(d *State, dst io.Writer) error { 1921 // Make sure it is sorted 1922 d.sort() 1923 1924 // make sure we have no uninitialized fields 1925 d.init() 1926 1927 // Ensure the version is set 1928 d.Version = StateVersion 1929 1930 // If the TFVersion is set, verify it. We used to just set the version 1931 // here, but this isn't safe since it changes the MD5 sum on some remote 1932 // state storage backends such as Atlas. We now leave it be if needed. 1933 if d.TFVersion != "" { 1934 if _, err := version.NewVersion(d.TFVersion); err != nil { 1935 return fmt.Errorf( 1936 "Error writing state, invalid version: %s\n\n"+ 1937 "The Terraform version when writing the state must be a semantic\n"+ 1938 "version.", 1939 d.TFVersion) 1940 } 1941 } 1942 1943 // Encode the data in a human-friendly way 1944 data, err := json.MarshalIndent(d, "", " ") 1945 if err != nil { 1946 return fmt.Errorf("Failed to encode state: %s", err) 1947 } 1948 1949 // We append a newline to the data because MarshalIndent doesn't 1950 data = append(data, '\n') 1951 1952 // Write the data out to the dst 1953 if _, err := io.Copy(dst, bytes.NewReader(data)); err != nil { 1954 return fmt.Errorf("Failed to write state: %v", err) 1955 } 1956 1957 return nil 1958 } 1959 1960 // moduleStateSort implements sort.Interface to sort module states 1961 type moduleStateSort []*ModuleState 1962 1963 func (s moduleStateSort) Len() int { 1964 return len(s) 1965 } 1966 1967 func (s moduleStateSort) Less(i, j int) bool { 1968 a := s[i] 1969 b := s[j] 1970 1971 // If the lengths are different, then the shorter one always wins 1972 if len(a.Path) != len(b.Path) { 1973 return len(a.Path) < len(b.Path) 1974 } 1975 1976 // Otherwise, compare lexically 1977 return strings.Join(a.Path, ".") < strings.Join(b.Path, ".") 1978 } 1979 1980 func (s moduleStateSort) Swap(i, j int) { 1981 s[i], s[j] = s[j], s[i] 1982 } 1983 1984 const stateValidateErrMultiModule = ` 1985 Multiple modules with the same path: %s 1986 1987 This means that there are multiple entries in the "modules" field 1988 in your state file that point to the same module. This will cause Terraform 1989 to behave in unexpected and error prone ways and is invalid. Please back up 1990 and modify your state file manually to resolve this. 1991 `