Class: Cloudspin::Stack::Instance

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
lib/cloudspin/stack/instance.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id:, stack_definition:, backend_config:, working_folder:, statefile_folder:) ⇒ Instance

Returns a new instance of Instance.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/cloudspin/stack/instance.rb', line 17

def initialize(id:,
               stack_definition:,
               backend_config:,
               working_folder:,
               statefile_folder:
              )
  validate_id(id)
  @id = id
  @stack_definition = stack_definition
  @backend_config = backend_config
  @working_folder = working_folder
  @statefile_folder = Pathname.new(statefile_folder).realdirpath.to_s
  @parameter_values = {}
  @resource_values = {}
end

Instance Attribute Details

#backend_configObject (readonly)

Returns the value of attribute backend_config.



10
11
12
# File 'lib/cloudspin/stack/instance.rb', line 10

def backend_config
  @backend_config
end

#idObject (readonly)

Returns the value of attribute id.



10
11
12
# File 'lib/cloudspin/stack/instance.rb', line 10

def id
  @id
end

#parameter_valuesObject (readonly)

Returns the value of attribute parameter_values.



10
11
12
# File 'lib/cloudspin/stack/instance.rb', line 10

def parameter_values
  @parameter_values
end

#resource_valuesObject (readonly)

Returns the value of attribute resource_values.



10
11
12
# File 'lib/cloudspin/stack/instance.rb', line 10

def resource_values
  @resource_values
end

#statefile_folderObject (readonly)

Returns the value of attribute statefile_folder.



10
11
12
# File 'lib/cloudspin/stack/instance.rb', line 10

def statefile_folder
  @statefile_folder
end

#working_folderObject (readonly)

Returns the value of attribute working_folder.



10
11
12
# File 'lib/cloudspin/stack/instance.rb', line 10

def working_folder
  @working_folder
end

Class Method Details

.from_definition_folder(id:, definition_folder:, instance_folder: '.') ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/cloudspin/stack/instance.rb', line 33

def self.from_definition_folder(id:, definition_folder:, instance_folder: '.')
  self.new(
    id: id,
    stack_definition: Definition.from_file(definition_folder + '/stack-definition.yaml'),
    backend_config: {},
    working_folder: instance_folder + '/work',
    statefile_folder: instance_folder + '/state'
  )
end

Instance Method Details

#add_config_from_yaml(yaml_file) ⇒ Object



57
58
59
60
61
# File 'lib/cloudspin/stack/instance.rb', line 57

def add_config_from_yaml(yaml_file)
  config = load_config_file(yaml_file)
  add_parameter_values(config['parameters']) if config['parameters']
  add_resource_values(config['resources']) if config['resources']
end

#add_parameter_values(new_parameter_values) ⇒ Object



49
50
51
# File 'lib/cloudspin/stack/instance.rb', line 49

def add_parameter_values(new_parameter_values)
  @parameter_values.merge!(new_parameter_values)
end

#add_resource_values(new_resource_values) ⇒ Object



53
54
55
# File 'lib/cloudspin/stack/instance.rb', line 53

def add_resource_values(new_resource_values)
  @resource_values.merge!(new_resource_values)
end

#downObject



123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/cloudspin/stack/instance.rb', line 123

def down
  RubyTerraform.clean(directory: working_folder)
  mkdir_p File.dirname(working_folder)
  cp_r @stack_definition.terraform_source_path, working_folder
  Dir.chdir(working_folder) do
    RubyTerraform.init(backend_config: backend_config)
    RubyTerraform.destroy(
      force: true,
      state: terraform_statefile,
      vars: terraform_variables
    )
  end
end

#down_dryObject



137
138
139
140
141
142
143
144
145
146
# File 'lib/cloudspin/stack/instance.rb', line 137

def down_dry
  down_command = RubyTerraform::Commands::Destroy.new
  command_line_builder = down_command.instantiate_builder
  configured_command = down_command.configure_command(command_line_builder, {
    :state => terraform_statefile,
    :vars => terraform_variables
  })
  built_command = configured_command.build
  "cd #{working_folder} && #{built_command.to_s}"
end

#load_config_file(yaml_file) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/cloudspin/stack/instance.rb', line 63

def load_config_file(yaml_file)
  if File.exists?(yaml_file)
    YAML.load_file(yaml_file) || {}
  else
    {}
  end
end

#plan(plan_destroy: false) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/cloudspin/stack/instance.rb', line 72

def plan(plan_destroy: false)
  RubyTerraform.clean(directory: working_folder)
  mkdir_p File.dirname(working_folder)
  cp_r @stack_definition.terraform_source_path, working_folder
  Dir.chdir(working_folder) do
    RubyTerraform.init(backend_config: backend_config)
    RubyTerraform.plan(
      destroy: plan_destroy,
      state: terraform_statefile,
      vars: terraform_variables
    )
  end
end

#plan_dry(plan_destroy: false) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/cloudspin/stack/instance.rb', line 86

def plan_dry(plan_destroy: false)
  plan_command = RubyTerraform::Commands::Plan.new
  command_line_builder = plan_command.instantiate_builder
  configured_command = plan_command.configure_command(command_line_builder, {
    :destroy => plan_destroy,
    :state => terraform_statefile,
    :vars => terraform_variables
  })
  built_command = configured_command.build
  "cd #{working_folder} && #{built_command.to_s}"
end

#terraform_statefileObject



154
155
156
# File 'lib/cloudspin/stack/instance.rb', line 154

def terraform_statefile
  statefile_folder + "/stack-#{id}.tfstate"
end

#terraform_variablesObject



148
149
150
151
152
# File 'lib/cloudspin/stack/instance.rb', line 148

def terraform_variables
  @parameter_values.merge(@resource_values) { |key, oldval, newval|
    raise "Duplicate values for terraform variable '#{key}' ('#{oldval}' and '#{newval}')"
  }
end

#upObject



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/cloudspin/stack/instance.rb', line 98

def up
  RubyTerraform.clean(directory: working_folder)
  mkdir_p File.dirname(working_folder)
  cp_r @stack_definition.terraform_source_path, working_folder
  Dir.chdir(working_folder) do
    RubyTerraform.init(backend_config: backend_config)
    RubyTerraform.apply(
      auto_approve: true,
      state: terraform_statefile,
      vars: terraform_variables
    )
  end
end

#up_dryObject



112
113
114
115
116
117
118
119
120
121
# File 'lib/cloudspin/stack/instance.rb', line 112

def up_dry
  up_command = RubyTerraform::Commands::Apply.new
  command_line_builder = up_command.instantiate_builder
  configured_command = up_command.configure_command(command_line_builder, {
    :state => terraform_statefile,
    :vars => terraform_variables
  })
  built_command = configured_command.build
  "cd #{working_folder} && #{built_command.to_s}"
end

#validate_id(raw_id) ⇒ Object



43
44
45
46
47
# File 'lib/cloudspin/stack/instance.rb', line 43

def validate_id(raw_id)
  raise "Stack instance ID '#{raw_id}' won't work. It needs to work as a filename." if /[^0-9A-Za-z.\-\_]/ =~ raw_id
  raise "Stack instance ID '#{raw_id}' won't work. No double dots allowed." if /\.\./ =~ raw_id
  raise "Stack instance ID '#{raw_id}' won't work. First character should be a letter." if /^[^A-Za-z]/ =~ raw_id
end