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