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