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