hashicorptools 0.2.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +5 -1
- data/Gemfile +8 -13
- data/VERSION +1 -1
- data/hashicorptools.gemspec +27 -46
- data/lib/hashicorptools.rb +0 -3
- data/lib/hashicorptools/ami_configs/standard-ami.json +1 -0
- data/lib/hashicorptools/auto_scaling_group.rb +4 -4
- data/lib/hashicorptools/code_deploy.rb +71 -25
- data/lib/hashicorptools/ec2_utilities.rb +5 -6
- data/lib/hashicorptools/packer.rb +59 -30
- data/lib/hashicorptools/update_launch_configuration.rb +2 -1
- data/lib/hashicorptools/variables.rb +1 -5
- data/spec/ec2_utilities_spec.rb +14 -0
- metadata +23 -71
- data/lib/hashicorptools/terraform.rb +0 -299
- data/spec/hashicorptools_spec.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1dfcc2c084abef69cad0b5b5860982b1389e399e23e539a979eb7fd32dd245e9
|
4
|
+
data.tar.gz: b5d51aa37497b9d61f6d7c0b7e1bcfc0e76fb6bee9857eb51e02ba2ddf8df350
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bad4f2253923af3acadf6c59846834a07bf8905dddbd8ccf1ca41920c98544dde39592c936b22f07d77763c86382e82a3983502a15c515a4b29b4b76bc90b4b6
|
7
|
+
data.tar.gz: 467388e24b4ea0f583dd1536834f21ed5e9c820feaf19f3347d0002b3106f91481886d6bd44549978c5bf652ceebf1bf116f5193304b4881a5c95abb6fb39252
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.6.6
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
|
-
# try to slowly migrate to v2 of the aws api
|
4
3
|
gem 'aws-sdk', '~> 2'
|
5
|
-
|
6
|
-
gem 'dynect_rest', '= 0.4.6'
|
7
|
-
|
8
|
-
gem 'aws-sdk-v1', '~> 1.67'
|
9
4
|
gem 'dotenv', '~> 2.2', '>= 2.2.1'
|
10
|
-
gem 'thor', '
|
11
|
-
gem 'activesupport', '
|
12
|
-
gem 'byebug', '
|
13
|
-
gem 'git', '
|
5
|
+
gem 'thor', '>= 0.20.0'
|
6
|
+
gem 'activesupport', '>= 5.1.4'
|
7
|
+
gem 'byebug', '>= 10.0.2'
|
8
|
+
gem 'git', '> 1.3'
|
14
9
|
|
15
10
|
group :development do
|
16
|
-
gem 'rspec', '
|
17
|
-
gem 'rdoc', '
|
18
|
-
gem 'bundler', '
|
19
|
-
gem 'juwelier',
|
11
|
+
gem 'rspec', '> 3.7'
|
12
|
+
gem 'rdoc', '> 3.12'
|
13
|
+
gem 'bundler', '> 2.0'
|
14
|
+
gem 'juwelier', git: 'https://github.com/flajann2/juwelier.git'
|
20
15
|
gem 'simplecov', '>= 0'
|
21
16
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
data/hashicorptools.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: hashicorptools 0.
|
5
|
+
# stub: hashicorptools 1.0.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "hashicorptools".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "1.0.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Nathan Woodhull".freeze]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2020-07-30"
|
15
15
|
s.description = "Wrappers for terraform and packer".freeze
|
16
16
|
s.email = "systems@controlshiftlabs.com".freeze
|
17
17
|
s.executables = ["ec2_host".freeze]
|
@@ -37,62 +37,43 @@ Gem::Specification.new do |s|
|
|
37
37
|
"lib/hashicorptools/ec2_utilities.rb",
|
38
38
|
"lib/hashicorptools/host.rb",
|
39
39
|
"lib/hashicorptools/packer.rb",
|
40
|
-
"lib/hashicorptools/terraform.rb",
|
41
40
|
"lib/hashicorptools/update_launch_configuration.rb",
|
42
41
|
"lib/hashicorptools/variables.rb",
|
43
|
-
"spec/
|
42
|
+
"spec/ec2_utilities_spec.rb",
|
44
43
|
"spec/spec_helper.rb"
|
45
44
|
]
|
46
45
|
s.homepage = "http://github.com/woodhull/hashicorptools".freeze
|
47
46
|
s.licenses = ["MIT".freeze]
|
48
|
-
s.rubygems_version = "
|
47
|
+
s.rubygems_version = "3.1.2".freeze
|
49
48
|
s.summary = "Wrappers for terraform and packer".freeze
|
50
49
|
|
51
50
|
if s.respond_to? :specification_version then
|
52
51
|
s.specification_version = 4
|
52
|
+
end
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
s.add_development_dependency(%q<juwelier>.freeze, [">= 2.4.7", "~> 2.4"])
|
67
|
-
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
68
|
-
else
|
69
|
-
s.add_dependency(%q<aws-sdk>.freeze, ["~> 2"])
|
70
|
-
s.add_dependency(%q<dynect_rest>.freeze, ["= 0.4.6"])
|
71
|
-
s.add_dependency(%q<aws-sdk-v1>.freeze, ["~> 1.67"])
|
72
|
-
s.add_dependency(%q<dotenv>.freeze, [">= 2.2.1", "~> 2.2"])
|
73
|
-
s.add_dependency(%q<thor>.freeze, ["= 0.20.0"])
|
74
|
-
s.add_dependency(%q<activesupport>.freeze, [">= 5.1.4", "~> 5.1"])
|
75
|
-
s.add_dependency(%q<byebug>.freeze, [">= 10.0.2", "~> 10.0"])
|
76
|
-
s.add_dependency(%q<git>.freeze, ["~> 1.3"])
|
77
|
-
s.add_dependency(%q<rspec>.freeze, ["~> 3.7"])
|
78
|
-
s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
|
79
|
-
s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
|
80
|
-
s.add_dependency(%q<juwelier>.freeze, [">= 2.4.7", "~> 2.4"])
|
81
|
-
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
82
|
-
end
|
54
|
+
if s.respond_to? :add_runtime_dependency then
|
55
|
+
s.add_runtime_dependency(%q<aws-sdk>.freeze, ["~> 2"])
|
56
|
+
s.add_runtime_dependency(%q<dotenv>.freeze, ["~> 2.2", ">= 2.2.1"])
|
57
|
+
s.add_runtime_dependency(%q<thor>.freeze, [">= 0.20.0"])
|
58
|
+
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 5.1.4"])
|
59
|
+
s.add_runtime_dependency(%q<byebug>.freeze, [">= 10.0.2"])
|
60
|
+
s.add_runtime_dependency(%q<git>.freeze, ["> 1.3"])
|
61
|
+
s.add_development_dependency(%q<rspec>.freeze, ["> 3.7"])
|
62
|
+
s.add_development_dependency(%q<rdoc>.freeze, ["> 3.12"])
|
63
|
+
s.add_development_dependency(%q<bundler>.freeze, ["> 2.0"])
|
64
|
+
s.add_development_dependency(%q<juwelier>.freeze, [">= 0"])
|
65
|
+
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
83
66
|
else
|
84
67
|
s.add_dependency(%q<aws-sdk>.freeze, ["~> 2"])
|
85
|
-
s.add_dependency(%q<
|
86
|
-
s.add_dependency(%q<
|
87
|
-
s.add_dependency(%q<
|
88
|
-
s.add_dependency(%q<
|
89
|
-
s.add_dependency(%q<
|
90
|
-
s.add_dependency(%q<
|
91
|
-
s.add_dependency(%q<
|
92
|
-
s.add_dependency(%q<
|
93
|
-
s.add_dependency(%q<
|
94
|
-
s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
|
95
|
-
s.add_dependency(%q<juwelier>.freeze, [">= 2.4.7", "~> 2.4"])
|
68
|
+
s.add_dependency(%q<dotenv>.freeze, ["~> 2.2", ">= 2.2.1"])
|
69
|
+
s.add_dependency(%q<thor>.freeze, [">= 0.20.0"])
|
70
|
+
s.add_dependency(%q<activesupport>.freeze, [">= 5.1.4"])
|
71
|
+
s.add_dependency(%q<byebug>.freeze, [">= 10.0.2"])
|
72
|
+
s.add_dependency(%q<git>.freeze, ["> 1.3"])
|
73
|
+
s.add_dependency(%q<rspec>.freeze, ["> 3.7"])
|
74
|
+
s.add_dependency(%q<rdoc>.freeze, ["> 3.12"])
|
75
|
+
s.add_dependency(%q<bundler>.freeze, ["> 2.0"])
|
76
|
+
s.add_dependency(%q<juwelier>.freeze, [">= 0"])
|
96
77
|
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
97
78
|
end
|
98
79
|
end
|
data/lib/hashicorptools.rb
CHANGED
@@ -2,9 +2,7 @@ require 'bundler/setup'
|
|
2
2
|
require 'dotenv'
|
3
3
|
require 'thor'
|
4
4
|
require 'active_support/all'
|
5
|
-
require 'aws-sdk-v1'
|
6
5
|
require 'aws-sdk'
|
7
|
-
require 'dynect_rest'
|
8
6
|
|
9
7
|
module Hashicorptools
|
10
8
|
end
|
@@ -13,7 +11,6 @@ require_relative 'hashicorptools/variables'
|
|
13
11
|
require_relative 'hashicorptools/ec2_utilities'
|
14
12
|
require_relative 'hashicorptools/auto_scaling_group'
|
15
13
|
require_relative 'hashicorptools/packer'
|
16
|
-
require_relative 'hashicorptools/terraform'
|
17
14
|
require_relative 'hashicorptools/host'
|
18
15
|
require_relative 'hashicorptools/update_launch_configuration'
|
19
16
|
require_relative 'hashicorptools/code_deploy'
|
@@ -2,7 +2,7 @@ require "timeout"
|
|
2
2
|
|
3
3
|
module Hashicorptools
|
4
4
|
class AutoScalingGroup
|
5
|
-
attr_accessor :name
|
5
|
+
attr_accessor :name, :region
|
6
6
|
|
7
7
|
def initialize(attrs = {})
|
8
8
|
attrs.each do |key,value|
|
@@ -115,15 +115,15 @@ module Hashicorptools
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def autoscaling
|
118
|
-
@autoscaling ||= Aws::AutoScaling::Client.new(region:
|
118
|
+
@autoscaling ||= Aws::AutoScaling::Client.new(region: region)
|
119
119
|
end
|
120
120
|
|
121
121
|
def ec2
|
122
|
-
@ec2 ||= Aws::EC2::Client.new(region:
|
122
|
+
@ec2 ||= Aws::EC2::Client.new(region: region)
|
123
123
|
end
|
124
124
|
|
125
125
|
def elb
|
126
|
-
@elb ||= Aws::ElasticLoadBalancing::Client.new(region:
|
126
|
+
@elb ||= Aws::ElasticLoadBalancing::Client.new(region: region)
|
127
127
|
end
|
128
128
|
|
129
129
|
def groups
|
@@ -7,52 +7,98 @@ require 'logger'
|
|
7
7
|
require 'thor'
|
8
8
|
|
9
9
|
module Hashicorptools
|
10
|
+
class RegionDeployment
|
11
|
+
attr_accessor :aws_region, :environment
|
12
|
+
|
13
|
+
def initialize(aws_region:, environment:)
|
14
|
+
@aws_region = aws_region
|
15
|
+
@environment = environment
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_deployment(commit_id, commit_message)
|
19
|
+
client = Aws::CodeDeploy::Client.new(region: aws_region)
|
20
|
+
response = client.create_deployment({
|
21
|
+
application_name: application_name,
|
22
|
+
deployment_group_name: "#{application_name}-#{@environment}",
|
23
|
+
revision: {
|
24
|
+
revision_type: 'GitHub',
|
25
|
+
git_hub_location: {
|
26
|
+
repository: "controlshift/#{application_name}",
|
27
|
+
commit_id: commit_id
|
28
|
+
}
|
29
|
+
},
|
30
|
+
description: (commit_message || "commit #{commit_id}").slice(0,99)
|
31
|
+
})
|
32
|
+
output "created deployment #{response.deployment_id}"
|
33
|
+
output "https://console.aws.amazon.com/codedeploy/home?region=#{aws_region}#/deployments/#{response.deployment_id}"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def application_name
|
39
|
+
raise "implement me"
|
40
|
+
end
|
41
|
+
|
42
|
+
def output(text)
|
43
|
+
puts "[#{aws_region}] #{text}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
10
47
|
class CodeDeploy < Thor
|
48
|
+
AWS_REGION_US_EAST_1 = 'us-east-1'
|
11
49
|
|
12
50
|
desc 'deploy', 'deploy latest code to environment'
|
13
|
-
option :environment, :
|
14
|
-
option :branch
|
51
|
+
option :environment, required: true
|
52
|
+
option :branch
|
53
|
+
option :aws_regions, type: :array
|
15
54
|
option :commit
|
16
55
|
def deploy
|
17
56
|
g = Git.open('..')
|
18
57
|
|
58
|
+
# We set defaults (depending on environment) for aws_regions if not passed in
|
59
|
+
aws_regions = options[:aws_regions] || default_regions
|
60
|
+
|
19
61
|
commit = if options[:commit].present?
|
20
62
|
g.gcommit(options[:commit])
|
21
63
|
else
|
22
|
-
|
64
|
+
branch = options[:branch].nil? ? :main : options[:branch].to_sym
|
65
|
+
g.checkout(branch)
|
23
66
|
g.log.first
|
24
67
|
end
|
25
68
|
|
69
|
+
puts "Deploying to environment #{options[:environment]} - regions: #{aws_regions.join(', ')}
|
70
|
+
commit: #{commit.sha}
|
71
|
+
message: #{commit.message}"
|
26
72
|
|
27
|
-
puts "
|
73
|
+
puts "Deploying for regions: #{aws_regions}"
|
28
74
|
|
29
|
-
|
75
|
+
threads = []
|
76
|
+
aws_regions.each_slice(2) do |aws_regions_batch|
|
77
|
+
puts "Deploying for batch of regions: #{aws_regions_batch}"
|
78
|
+
aws_regions_batch.each do |aws_region|
|
79
|
+
thread = Thread.new{ region_deployment(aws_region).create_deployment(commit.sha, commit.message) }
|
80
|
+
threads.push(thread)
|
81
|
+
end
|
82
|
+
|
83
|
+
threads.each_with_index do |thread, index|
|
84
|
+
begin
|
85
|
+
thread.join
|
86
|
+
rescue Exception => e
|
87
|
+
# Don't quit whole program on exception in thread, just print exception and exit thread
|
88
|
+
puts "[#{aws_regions[index]}] EXCEPTION: #{e}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
30
92
|
end
|
31
93
|
|
32
94
|
private
|
33
95
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
client = Aws::CodeDeploy::Client.new
|
38
|
-
response = client.create_deployment({
|
39
|
-
application_name: application_name,
|
40
|
-
deployment_group_name: "#{application_name}-#{options[:environment]}",
|
41
|
-
revision: {
|
42
|
-
revision_type: 'GitHub',
|
43
|
-
git_hub_location: {
|
44
|
-
repository: "controlshift/#{application_name}",
|
45
|
-
commit_id: commit_id
|
46
|
-
}
|
47
|
-
},
|
48
|
-
description: (commit_message || "commit #{commit_id}").slice(0,99)
|
49
|
-
})
|
50
|
-
puts "created deployment #{response.deployment_id}"
|
51
|
-
puts "https://console.aws.amazon.com/codedeploy/home?region=#{ENV['AWS_REGION']}#/deployments/#{response.deployment_id}"
|
96
|
+
def region_deployment(aws_region)
|
97
|
+
RegionDeployment.new(aws_region: aws_region, environment: options[:environment])
|
52
98
|
end
|
53
99
|
|
54
|
-
def
|
55
|
-
|
100
|
+
def default_regions
|
101
|
+
[AWS_REGION_US_EAST_1]
|
56
102
|
end
|
57
103
|
end
|
58
104
|
end
|
@@ -5,7 +5,8 @@ module Hashicorptools
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def amis(tag = tag_name)
|
8
|
-
|
8
|
+
images = ec2.describe_images({owners: ['self'], filters: [{name: 'tag:Name', values: [tag]}]}).images
|
9
|
+
sort_by_created_at(images)
|
9
10
|
end
|
10
11
|
|
11
12
|
def ec2
|
@@ -17,17 +18,15 @@ module Hashicorptools
|
|
17
18
|
'us-east-1'
|
18
19
|
end
|
19
20
|
|
20
|
-
@_ec2 =
|
21
|
+
@_ec2 = Aws::EC2::Client.new(region: reg)
|
21
22
|
end
|
22
23
|
|
23
24
|
def vpc_with_name(name)
|
24
|
-
|
25
|
-
vpcs.first
|
25
|
+
ec2.describe_vpcs({filters: [{name: 'tag:Name', values: [name]}]}).vpcs.first
|
26
26
|
end
|
27
27
|
|
28
28
|
def internet_gateway_for_vpc(vpc_id)
|
29
|
-
|
30
|
-
igs.first
|
29
|
+
ec2.describe_internet_gateways({filters: [{name: 'attachment.vpc-id', values: [vpc_id]}]}).internet_gateways.first
|
31
30
|
end
|
32
31
|
|
33
32
|
def sort_by_created_at(collection)
|
@@ -33,7 +33,7 @@ module Hashicorptools
|
|
33
33
|
|
34
34
|
desc "list", "list all available amis"
|
35
35
|
def list
|
36
|
-
|
36
|
+
amis_in_region(region).each do |ami|
|
37
37
|
puts ami.image_id
|
38
38
|
end
|
39
39
|
end
|
@@ -45,7 +45,7 @@ module Hashicorptools
|
|
45
45
|
|
46
46
|
desc "clean_snapshots", "clean obsolete EBS snapshots not associated with any AMI"
|
47
47
|
def clean_snapshots
|
48
|
-
snapshots = ec2.
|
48
|
+
snapshots = ec2.describe_snapshots({owner_ids: ['self']}).snapshots
|
49
49
|
snapshots.each do |snapshot|
|
50
50
|
match = snapshot.description.match(/Created by CreateImage\(.+\) for (ami-[0-9a-f]+) from vol-.+/)
|
51
51
|
if match.nil?
|
@@ -54,23 +54,28 @@ module Hashicorptools
|
|
54
54
|
end
|
55
55
|
|
56
56
|
ami_id = match[1]
|
57
|
-
unless
|
58
|
-
puts "Removing obsolete snapshot #{snapshot.
|
59
|
-
|
60
|
-
snapshot.delete
|
57
|
+
unless Aws::EC2::Image.new(ami_id, region: region).exists?
|
58
|
+
puts "Removing obsolete snapshot #{snapshot.snapshot_id} - #{snapshot.description}"
|
59
|
+
ec2.delete_snapshot({snapshot_id: snapshot.snapshot_id})
|
61
60
|
end
|
62
61
|
end
|
63
62
|
end
|
64
63
|
|
65
64
|
desc "boot", "start up an instance of the latest version of AMI"
|
66
65
|
def boot
|
67
|
-
run_instances_resp = ec2.run_instances(
|
66
|
+
run_instances_resp = ec2.run_instances({
|
67
|
+
image_id: current_ami('base-image').image_id,
|
68
68
|
min_count: 1,
|
69
69
|
max_count: 1,
|
70
|
-
instance_type: "t2.micro"
|
70
|
+
instance_type: "t2.micro"
|
71
|
+
})
|
71
72
|
|
72
|
-
ec2.create_tags(
|
73
|
-
|
73
|
+
ec2.create_tags({
|
74
|
+
resources: run_instances_resp.instances.collect(&:instance_id),
|
75
|
+
tags: [ {key: 'Name', value: "packer test boot #{tag_name}"},
|
76
|
+
{key: 'environment', value: 'packer-development'},
|
77
|
+
{key: 'temporary', value: 'kill me'}]
|
78
|
+
})
|
74
79
|
|
75
80
|
require 'byebug'
|
76
81
|
byebug
|
@@ -104,7 +109,7 @@ module Hashicorptools
|
|
104
109
|
end
|
105
110
|
|
106
111
|
def ami_building_subnet_id
|
107
|
-
ec2.
|
112
|
+
ec2.describe_subnets({filters: [{name: "vpc-id", values: [ami_building_vpc_id]}]}).subnets.first.subnet_id
|
108
113
|
end
|
109
114
|
|
110
115
|
def format_variable(key, value)
|
@@ -127,39 +132,52 @@ module Hashicorptools
|
|
127
132
|
'us-east-1'
|
128
133
|
end
|
129
134
|
|
130
|
-
def auto_scaling
|
131
|
-
@auto_scaling ||= Aws::AutoScaling::Client.new(region:
|
135
|
+
def auto_scaling(client_region=region)
|
136
|
+
@auto_scaling ||= Aws::AutoScaling::Client.new(region: client_region)
|
132
137
|
end
|
133
138
|
|
134
|
-
def
|
135
|
-
@
|
139
|
+
def regional_ec2_client(client_region=region)
|
140
|
+
@_regional_ec2_clients = {} if @_regional_ec2_clients.nil?
|
141
|
+
@_regional_ec2_clients[client_region] ||= Aws::EC2::Client.new(region: client_region)
|
136
142
|
end
|
137
143
|
|
138
|
-
def amis_in_use
|
139
|
-
launch_configs = auto_scaling.describe_launch_configurations
|
144
|
+
def amis_in_use(client_region)
|
145
|
+
launch_configs = auto_scaling(client_region).describe_launch_configurations
|
140
146
|
image_ids = launch_configs.data['launch_configurations'].collect{|lc| lc.image_id}.flatten
|
141
147
|
|
142
|
-
ec2_reservations =
|
148
|
+
ec2_reservations = regional_ec2_client(client_region).describe_instances
|
143
149
|
image_ids << ec2_reservations.reservations.collect{|res| res.instances.collect{|r| r.image_id}}.flatten
|
144
150
|
image_ids.flatten
|
145
151
|
end
|
146
152
|
|
153
|
+
def ami_regions
|
154
|
+
['us-east-1', 'eu-central-1']
|
155
|
+
end
|
156
|
+
|
147
157
|
def clean_amis
|
148
|
-
|
149
|
-
|
150
|
-
|
158
|
+
ami_regions.each do |ami_region|
|
159
|
+
clean_amis_for_region(ami_region)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def clean_amis_for_region(region_to_clean)
|
164
|
+
ami_ids = amis_in_region(region_to_clean).collect{|a| a.image_id}
|
165
|
+
ami_ids_to_remove = ami_ids - amis_in_use(region_to_clean)
|
166
|
+
potential_amis_to_remove = amis_in_region(region_to_clean)
|
151
167
|
potential_amis_to_remove.keep_if {|a| ami_ids_to_remove.include?(a.image_id) }
|
152
168
|
|
153
169
|
if potential_amis_to_remove.size > NUMBER_OF_AMIS_TO_KEEP
|
154
170
|
amis_to_remove = potential_amis_to_remove[NUMBER_OF_AMIS_TO_KEEP..-1]
|
155
171
|
amis_to_keep = potential_amis_to_remove[0..(NUMBER_OF_AMIS_TO_KEEP-1)]
|
156
172
|
|
157
|
-
puts "Deregistering old AMIs..."
|
173
|
+
puts "Deregistering old AMIs in #{region_to_clean}..."
|
158
174
|
amis_to_remove.each do |ami|
|
159
175
|
ebs_mappings = ami.block_device_mappings
|
160
176
|
puts "Deregistering #{ami.image_id}"
|
161
|
-
|
162
|
-
|
177
|
+
regional_ec2_client(region_to_clean).deregister_image({
|
178
|
+
image_id: ami.image_id
|
179
|
+
})
|
180
|
+
delete_ami_snapshots(ebs_mappings, snapshot_region: region_to_clean)
|
163
181
|
end
|
164
182
|
|
165
183
|
puts "Currently active AMIs..."
|
@@ -167,15 +185,26 @@ module Hashicorptools
|
|
167
185
|
puts ami.image_id
|
168
186
|
end
|
169
187
|
else
|
170
|
-
puts "no AMIs to clean."
|
188
|
+
puts "no AMIs to clean in #{region_to_clean}."
|
171
189
|
end
|
172
190
|
end
|
173
191
|
|
174
|
-
def
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
192
|
+
def amis_in_region(ami_region)
|
193
|
+
images = regional_ec2_client(ami_region).describe_images({
|
194
|
+
owners: ['self'],
|
195
|
+
filters: [{name: 'tag:Name', values: [tag_name]}]
|
196
|
+
}).images
|
197
|
+
sort_by_created_at(images)
|
198
|
+
end
|
199
|
+
|
200
|
+
def delete_ami_snapshots(ebs_mappings, snapshot_region:)
|
201
|
+
ec2_client = regional_ec2_client(snapshot_region)
|
202
|
+
|
203
|
+
ebs_mappings.each do |ebs_mapping|
|
204
|
+
unless ebs_mapping.ebs.nil?
|
205
|
+
puts "Deleting snapshot #{ebs_mapping.ebs.snapshot_id}"
|
206
|
+
ec2_client.delete_snapshot({snapshot_id: ebs_mapping.ebs.snapshot_id})
|
207
|
+
end
|
179
208
|
end
|
180
209
|
end
|
181
210
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module Hashicorptools
|
2
2
|
class UpdateLaunchConfiguration < Thor
|
3
3
|
desc 'deploy ASG_NAME', 'recycle instances in the ASG with no downtime'
|
4
|
+
option :aws_region, default: 'us-east-1'
|
4
5
|
def deploy(asg_name)
|
5
|
-
asg = AutoScalingGroup.new(name: asg_name)
|
6
|
+
asg = AutoScalingGroup.new(name: asg_name, region: options[:aws_region])
|
6
7
|
if asg.group.nil?
|
7
8
|
raise "could not find asg #{asg_name}"
|
8
9
|
end
|
@@ -1,12 +1,8 @@
|
|
1
1
|
module Hashicorptools
|
2
2
|
module Variables
|
3
|
-
def aws_credentials_settings(settings_overrides = {})
|
4
|
-
{aws_access_key: ENV['AWS_ACCESS_KEY_ID'],
|
5
|
-
aws_secret_key: ENV['AWS_SECRET_ACCESS_KEY']}.merge(settings_overrides)
|
6
|
-
end
|
7
3
|
|
8
4
|
def variables(settings_overrides = {})
|
9
|
-
|
5
|
+
settings_overrides.collect{|key,value| format_variable(key, value)}.join(' ')
|
10
6
|
end
|
11
7
|
|
12
8
|
protected
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Hashicorptools::Ec2Utilities, type: :helper do
|
4
|
+
let(:including_class) { Class.new { include Hashicorptools::Ec2Utilities } }
|
5
|
+
|
6
|
+
subject { including_class.new }
|
7
|
+
|
8
|
+
describe '#ec2' do
|
9
|
+
it 'should return a client' do
|
10
|
+
client = subject.ec2
|
11
|
+
expect(client).to be_a Aws::EC2::Client
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashicorptools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Woodhull
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -25,65 +25,37 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.4.6
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.4.6
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: aws-sdk-v1
|
28
|
+
name: dotenv
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.67'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: dotenv
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
33
|
+
version: '2.2'
|
59
34
|
- - ">="
|
60
35
|
- !ruby/object:Gem::Version
|
61
36
|
version: 2.2.1
|
62
|
-
- - "~>"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '2.2'
|
65
37
|
type: :runtime
|
66
38
|
prerelease: false
|
67
39
|
version_requirements: !ruby/object:Gem::Requirement
|
68
40
|
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: 2.2.1
|
72
41
|
- - "~>"
|
73
42
|
- !ruby/object:Gem::Version
|
74
43
|
version: '2.2'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.2.1
|
75
47
|
- !ruby/object:Gem::Dependency
|
76
48
|
name: thor
|
77
49
|
requirement: !ruby/object:Gem::Requirement
|
78
50
|
requirements:
|
79
|
-
- -
|
51
|
+
- - ">="
|
80
52
|
- !ruby/object:Gem::Version
|
81
53
|
version: 0.20.0
|
82
54
|
type: :runtime
|
83
55
|
prerelease: false
|
84
56
|
version_requirements: !ruby/object:Gem::Requirement
|
85
57
|
requirements:
|
86
|
-
- -
|
58
|
+
- - ">="
|
87
59
|
- !ruby/object:Gem::Version
|
88
60
|
version: 0.20.0
|
89
61
|
- !ruby/object:Gem::Dependency
|
@@ -93,9 +65,6 @@ dependencies:
|
|
93
65
|
- - ">="
|
94
66
|
- !ruby/object:Gem::Version
|
95
67
|
version: 5.1.4
|
96
|
-
- - "~>"
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version: '5.1'
|
99
68
|
type: :runtime
|
100
69
|
prerelease: false
|
101
70
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -103,9 +72,6 @@ dependencies:
|
|
103
72
|
- - ">="
|
104
73
|
- !ruby/object:Gem::Version
|
105
74
|
version: 5.1.4
|
106
|
-
- - "~>"
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '5.1'
|
109
75
|
- !ruby/object:Gem::Dependency
|
110
76
|
name: byebug
|
111
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,9 +79,6 @@ dependencies:
|
|
113
79
|
- - ">="
|
114
80
|
- !ruby/object:Gem::Version
|
115
81
|
version: 10.0.2
|
116
|
-
- - "~>"
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '10.0'
|
119
82
|
type: :runtime
|
120
83
|
prerelease: false
|
121
84
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -123,85 +86,76 @@ dependencies:
|
|
123
86
|
- - ">="
|
124
87
|
- !ruby/object:Gem::Version
|
125
88
|
version: 10.0.2
|
126
|
-
- - "~>"
|
127
|
-
- !ruby/object:Gem::Version
|
128
|
-
version: '10.0'
|
129
89
|
- !ruby/object:Gem::Dependency
|
130
90
|
name: git
|
131
91
|
requirement: !ruby/object:Gem::Requirement
|
132
92
|
requirements:
|
133
|
-
- - "
|
93
|
+
- - ">"
|
134
94
|
- !ruby/object:Gem::Version
|
135
95
|
version: '1.3'
|
136
96
|
type: :runtime
|
137
97
|
prerelease: false
|
138
98
|
version_requirements: !ruby/object:Gem::Requirement
|
139
99
|
requirements:
|
140
|
-
- - "
|
100
|
+
- - ">"
|
141
101
|
- !ruby/object:Gem::Version
|
142
102
|
version: '1.3'
|
143
103
|
- !ruby/object:Gem::Dependency
|
144
104
|
name: rspec
|
145
105
|
requirement: !ruby/object:Gem::Requirement
|
146
106
|
requirements:
|
147
|
-
- - "
|
107
|
+
- - ">"
|
148
108
|
- !ruby/object:Gem::Version
|
149
109
|
version: '3.7'
|
150
110
|
type: :development
|
151
111
|
prerelease: false
|
152
112
|
version_requirements: !ruby/object:Gem::Requirement
|
153
113
|
requirements:
|
154
|
-
- - "
|
114
|
+
- - ">"
|
155
115
|
- !ruby/object:Gem::Version
|
156
116
|
version: '3.7'
|
157
117
|
- !ruby/object:Gem::Dependency
|
158
118
|
name: rdoc
|
159
119
|
requirement: !ruby/object:Gem::Requirement
|
160
120
|
requirements:
|
161
|
-
- - "
|
121
|
+
- - ">"
|
162
122
|
- !ruby/object:Gem::Version
|
163
123
|
version: '3.12'
|
164
124
|
type: :development
|
165
125
|
prerelease: false
|
166
126
|
version_requirements: !ruby/object:Gem::Requirement
|
167
127
|
requirements:
|
168
|
-
- - "
|
128
|
+
- - ">"
|
169
129
|
- !ruby/object:Gem::Version
|
170
130
|
version: '3.12'
|
171
131
|
- !ruby/object:Gem::Dependency
|
172
132
|
name: bundler
|
173
133
|
requirement: !ruby/object:Gem::Requirement
|
174
134
|
requirements:
|
175
|
-
- - "
|
135
|
+
- - ">"
|
176
136
|
- !ruby/object:Gem::Version
|
177
|
-
version: '
|
137
|
+
version: '2.0'
|
178
138
|
type: :development
|
179
139
|
prerelease: false
|
180
140
|
version_requirements: !ruby/object:Gem::Requirement
|
181
141
|
requirements:
|
182
|
-
- - "
|
142
|
+
- - ">"
|
183
143
|
- !ruby/object:Gem::Version
|
184
|
-
version: '
|
144
|
+
version: '2.0'
|
185
145
|
- !ruby/object:Gem::Dependency
|
186
146
|
name: juwelier
|
187
147
|
requirement: !ruby/object:Gem::Requirement
|
188
148
|
requirements:
|
189
149
|
- - ">="
|
190
150
|
- !ruby/object:Gem::Version
|
191
|
-
version:
|
192
|
-
- - "~>"
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '2.4'
|
151
|
+
version: '0'
|
195
152
|
type: :development
|
196
153
|
prerelease: false
|
197
154
|
version_requirements: !ruby/object:Gem::Requirement
|
198
155
|
requirements:
|
199
156
|
- - ">="
|
200
157
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
202
|
-
- - "~>"
|
203
|
-
- !ruby/object:Gem::Version
|
204
|
-
version: '2.4'
|
158
|
+
version: '0'
|
205
159
|
- !ruby/object:Gem::Dependency
|
206
160
|
name: simplecov
|
207
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,10 +196,9 @@ files:
|
|
242
196
|
- lib/hashicorptools/ec2_utilities.rb
|
243
197
|
- lib/hashicorptools/host.rb
|
244
198
|
- lib/hashicorptools/packer.rb
|
245
|
-
- lib/hashicorptools/terraform.rb
|
246
199
|
- lib/hashicorptools/update_launch_configuration.rb
|
247
200
|
- lib/hashicorptools/variables.rb
|
248
|
-
- spec/
|
201
|
+
- spec/ec2_utilities_spec.rb
|
249
202
|
- spec/spec_helper.rb
|
250
203
|
homepage: http://github.com/woodhull/hashicorptools
|
251
204
|
licenses:
|
@@ -266,8 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
219
|
- !ruby/object:Gem::Version
|
267
220
|
version: '0'
|
268
221
|
requirements: []
|
269
|
-
|
270
|
-
rubygems_version: 2.7.6
|
222
|
+
rubygems_version: 3.1.2
|
271
223
|
signing_key:
|
272
224
|
specification_version: 4
|
273
225
|
summary: Wrappers for terraform and packer
|
@@ -1,299 +0,0 @@
|
|
1
|
-
module Hashicorptools
|
2
|
-
class Terraform < Thor
|
3
|
-
TERRAFORM_VERSION = '0.11.0'
|
4
|
-
|
5
|
-
include Ec2Utilities
|
6
|
-
include Variables
|
7
|
-
|
8
|
-
desc 'bootstrap', 'terraform a new infrastructure from scratch'
|
9
|
-
option :environment, :required => true
|
10
|
-
def bootstrap
|
11
|
-
apply
|
12
|
-
end
|
13
|
-
|
14
|
-
desc 'init', 'install providers into local terraform'
|
15
|
-
option :environment, :required => true
|
16
|
-
def init
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
[:apply, :plan, :destroy, :pull, :refresh].each do |cmd|
|
21
|
-
desc cmd, "terraform #{cmd}"
|
22
|
-
option :environment, :required => true
|
23
|
-
option :debug, :required => false
|
24
|
-
|
25
|
-
define_method cmd do
|
26
|
-
send("_#{cmd}")
|
27
|
-
end
|
28
|
-
|
29
|
-
no_commands do
|
30
|
-
define_method "_#{cmd}" do |settings_overrides = {}|
|
31
|
-
enforce_version!
|
32
|
-
raise 'invalid environment' unless ['staging', 'production'].include?(options[:environment])
|
33
|
-
|
34
|
-
execute(state_path, var_file_path) do
|
35
|
-
|
36
|
-
settings_overrides
|
37
|
-
.merge!({ app_environment: options[:environment] }
|
38
|
-
.merge(env_variable_keys)
|
39
|
-
.merge(settings)
|
40
|
-
.merge(shared_plan_variables))
|
41
|
-
|
42
|
-
send("before_#{cmd}")
|
43
|
-
|
44
|
-
terraform_command = "terraform #{cmd} #{variables(settings_overrides)} -state #{state_path} #{var_file_param} #{config_directory}"
|
45
|
-
|
46
|
-
if (options[:debug])
|
47
|
-
puts "[DEBUG] running command: '#{terraform_command}"
|
48
|
-
end
|
49
|
-
|
50
|
-
result = system terraform_command
|
51
|
-
|
52
|
-
if result
|
53
|
-
send("after_#{cmd}")
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
define_method "before_#{cmd}" do
|
59
|
-
# no-op
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
no_commands do
|
64
|
-
define_method "before_shared_#{cmd}" do
|
65
|
-
# no-op
|
66
|
-
end
|
67
|
-
|
68
|
-
define_method "after_#{cmd}" do
|
69
|
-
# no-op
|
70
|
-
end
|
71
|
-
|
72
|
-
define_method "after_shared_#{cmd}" do
|
73
|
-
# no-op
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
desc cmd, "terraform #{cmd} for shared plan"
|
78
|
-
option :debug, :required => false
|
79
|
-
define_method "shared_#{cmd}" do
|
80
|
-
enforce_version!
|
81
|
-
|
82
|
-
execute(shared_state_path) do
|
83
|
-
send("before_shared_#{cmd}")
|
84
|
-
|
85
|
-
terraform_command = "terraform #{cmd} #{variables(env_variable_keys.merge(settings))} -state #{shared_state_path} #{shared_config_directory}"
|
86
|
-
if (options[:debug])
|
87
|
-
puts "[DEBUG] running command: '#{terraform_command}"
|
88
|
-
end
|
89
|
-
result = system terraform_command
|
90
|
-
|
91
|
-
if result
|
92
|
-
send("after_shared_#{cmd}")
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
desc 'output', 'terraform output'
|
99
|
-
option :environment, :required => true
|
100
|
-
option :name, :required => true
|
101
|
-
def output
|
102
|
-
execute(state_path) do
|
103
|
-
system output_cmd(state_path, options[:name])
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
desc 'shared_output', 'terraform output for shared plan'
|
108
|
-
option :name, :required => true
|
109
|
-
def shared_output
|
110
|
-
execute(shared_state_path) do
|
111
|
-
system output_cmd(shared_state_path, options[:name])
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
desc 'taint', 'terraform taint'
|
116
|
-
option :environment, :required => true
|
117
|
-
option :name, :required => true
|
118
|
-
option :module, :required => false
|
119
|
-
def taint
|
120
|
-
execute(state_path) do
|
121
|
-
if options[:module].present?
|
122
|
-
system "terraform taint -module #{options[:module]} -state #{state_path} #{options[:name]}"
|
123
|
-
else
|
124
|
-
system "terraform taint -state #{state_path} #{options[:name]}"
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
desc 'shared_taint', 'terraform taint for shared plan'
|
130
|
-
option :name, :required => true
|
131
|
-
option :module, :required => false
|
132
|
-
def shared_taint
|
133
|
-
execute(shared_state_path) do
|
134
|
-
if options[:module].present?
|
135
|
-
system "terraform taint -module #{options[:module]} -state #{shared_state_path} #{options[:name]}"
|
136
|
-
else
|
137
|
-
system "terraform taint -state #{shared_state_path} #{options[:name]}"
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
desc 'show', 'terraform show'
|
143
|
-
option :environment, :required => true
|
144
|
-
def show
|
145
|
-
execute(state_path) do
|
146
|
-
system "terraform show #{state_path}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
desc 'shared_show', 'terraform show for shared plan'
|
151
|
-
def shared_show
|
152
|
-
execute(shared_state_path) do
|
153
|
-
system "terraform show #{shared_state_path}"
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
desc "console", "interactive session"
|
158
|
-
def console
|
159
|
-
require 'pry-byebug'
|
160
|
-
binding.pry
|
161
|
-
end
|
162
|
-
|
163
|
-
protected
|
164
|
-
|
165
|
-
def var_file_param
|
166
|
-
File.exist?(var_file_path) ?
|
167
|
-
"-var-file #{var_file_path}" :
|
168
|
-
""
|
169
|
-
end
|
170
|
-
|
171
|
-
def execute(state_file_path, var_file_path=nil)
|
172
|
-
begin
|
173
|
-
yield
|
174
|
-
rescue StandardError => e
|
175
|
-
puts e.message
|
176
|
-
puts e.backtrace
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def state_path
|
181
|
-
"#{config_environment_path}/#{options[:environment]}.tfstate"
|
182
|
-
end
|
183
|
-
|
184
|
-
def shared_state_path
|
185
|
-
"#{shared_config_directory}/shared.tfstate"
|
186
|
-
end
|
187
|
-
|
188
|
-
def var_file_path
|
189
|
-
"#{config_environment_path}/variables.tfvars"
|
190
|
-
end
|
191
|
-
|
192
|
-
def config_directory
|
193
|
-
"config/infrastructure/#{infrastructure}"
|
194
|
-
end
|
195
|
-
|
196
|
-
def shared_config_directory
|
197
|
-
"config/infrastructure/#{infrastructure}/shared"
|
198
|
-
end
|
199
|
-
|
200
|
-
def config_environment_path
|
201
|
-
"#{config_directory}/environments/#{options[:environment]}"
|
202
|
-
end
|
203
|
-
|
204
|
-
def infrastructure
|
205
|
-
raise 'implement me'
|
206
|
-
end
|
207
|
-
|
208
|
-
def output_cmd(state_file_path, name=nil)
|
209
|
-
"terraform output -state=#{state_file_path} #{name}"
|
210
|
-
end
|
211
|
-
|
212
|
-
def output_variable(state_file_path, name)
|
213
|
-
`#{output_cmd(state_file_path, name)}`.chomp
|
214
|
-
end
|
215
|
-
|
216
|
-
def output_variables(state_file_path)
|
217
|
-
raw_plan_output = `#{output_cmd(state_file_path)}`
|
218
|
-
parse_key_value_variables(raw_plan_output)
|
219
|
-
end
|
220
|
-
|
221
|
-
def var_file_variables
|
222
|
-
raise "Vars file #{var_file_path} does not exist" unless File.exist?(var_file_path)
|
223
|
-
|
224
|
-
raw_var_file_variables = File.read(var_file_path)
|
225
|
-
parse_key_value_variables(raw_var_file_variables)
|
226
|
-
end
|
227
|
-
|
228
|
-
def terraform_version
|
229
|
-
version_string = `terraform version`.chomp
|
230
|
-
version = /(\d+.\d+.\d+)/.match(version_string)
|
231
|
-
version[0]
|
232
|
-
end
|
233
|
-
|
234
|
-
def enforce_version!
|
235
|
-
if Gem::Version.new(terraform_version) < Gem::Version.new(TERRAFORM_VERSION)
|
236
|
-
raise "Terraform #{terraform_version} is out of date, please upgrade"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def settings
|
241
|
-
{} # override me to pass more variables into the terraform plan.
|
242
|
-
end
|
243
|
-
|
244
|
-
def asg_launch_config_name(asg_name)
|
245
|
-
asg_client = Aws::AutoScaling::Client.new(region: 'us-east-1')
|
246
|
-
group = asg_client.describe_auto_scaling_groups(auto_scaling_group_names: [asg_name]).auto_scaling_groups.first
|
247
|
-
group.try(:launch_configuration_name)
|
248
|
-
end
|
249
|
-
|
250
|
-
def env_variable_keys
|
251
|
-
{} # override me to pass environmental variables into the terraform plan
|
252
|
-
end
|
253
|
-
|
254
|
-
def shared_plan_variables
|
255
|
-
if File.exist?(shared_state_path)
|
256
|
-
output_variables(shared_state_path)
|
257
|
-
else
|
258
|
-
{}
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
def fetch_terraform_modules
|
263
|
-
system "terraform get -update=true #{config_directory}"
|
264
|
-
end
|
265
|
-
|
266
|
-
def current_tfstate
|
267
|
-
return @current_tfstate if defined?(@current_tfstate)
|
268
|
-
raw_conf = File.read(state_path)
|
269
|
-
@current_tfstate = JSON.parse(raw_conf)
|
270
|
-
end
|
271
|
-
|
272
|
-
def read_config_file(path)
|
273
|
-
File.new('config/' + path).read
|
274
|
-
template = ERB.new File.new("config/#{path}").read, nil, "%"
|
275
|
-
template.result(OpenStruct.new(options).instance_eval { binding })
|
276
|
-
end
|
277
|
-
|
278
|
-
def dynect
|
279
|
-
@dynect ||= DynectRest.new("controlshiftlabs", ENV['DYNECT_USERNAME'], ENV['DYNECT_PASSWORD'], "controlshiftlabs.com")
|
280
|
-
end
|
281
|
-
|
282
|
-
def dns_record_exists?(parent_node_fqdn, record)
|
283
|
-
dynect.node_list(nil, parent_node_fqdn).include?(record.fqdn)
|
284
|
-
end
|
285
|
-
|
286
|
-
private
|
287
|
-
|
288
|
-
def parse_key_value_variables(vars_string)
|
289
|
-
vars = {}
|
290
|
-
vars_string.split("\n").each do |string_var|
|
291
|
-
next if string_var.blank?
|
292
|
-
key, value = string_var.split("=")
|
293
|
-
vars[key.strip] = value.strip.gsub('"', '')
|
294
|
-
end
|
295
|
-
|
296
|
-
vars
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|