hashicorptools 0.1.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4692b4e530bde9683f94ab831155926ce8b479aa
4
- data.tar.gz: c90b5a4d1d0fd216aec3a53e83ce57b4d81184f6
2
+ SHA256:
3
+ metadata.gz: 254a2ff3deed5490e6c62c5b07dcddd20f60488e4f9dca3821ee931363ce37cc
4
+ data.tar.gz: 1e8f691dfb3e803620e949651c8a2a68c871f783182c7bf48c07a247d404e99c
5
5
  SHA512:
6
- metadata.gz: 05d7b64814446f085f7f03883de44eb47b975a202d07e9154af125439e506e7783645d4aa55514210a2c0100f9bdc57a2174030888014bb9fb9743b52a5d05ea
7
- data.tar.gz: bbe1ed16b551f5123503afeb086acc5cca65499e1eb0b6a4939c0c4c1c5830ac2bedf4aa09dea714c3e311c811981c602c946c5208096400254deda9687829ef
6
+ metadata.gz: c48cdfba1b075d54763e14930b200cc89c7926e7d4ec6fabaf8cc3b64f7e4b87076944910ca21c07960522d126134a5c5a94db83d2c4988a6f19907b195f71ab
7
+ data.tar.gz: 2155084c9795853030119225cd7534e710870c9f3bba04ee97d44852e2583d9d3009e0298c27eef8d953dc42d67f8b087deb5b41d1177a02ecfd8877f655624c
@@ -1 +1 @@
1
- ruby-2.3.4
1
+ ruby-2.6.6
@@ -1,3 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.2.5"
3
+ - "2.6.6"
4
+ # TravisCI uses Bundler 1 by default, but we want Bundler 2
5
+ # https://docs.travis-ci.com/user/languages/ruby/#bundler-20
6
+ before_install:
7
+ - gem install bundler
data/Gemfile CHANGED
@@ -3,21 +3,19 @@ source "http://rubygems.org"
3
3
  # try to slowly migrate to v2 of the aws api
4
4
  gem 'aws-sdk', '~> 2'
5
5
 
6
- gem 'dynect_rest'
6
+ gem 'dynect_rest', '= 0.4.6'
7
7
 
8
- gem 'aws-sdk-v1'
9
- gem 'dotenv'
10
- gem 'thor'
11
- gem 'activesupport'
12
- gem 'byebug'
13
- gem 'git'
8
+ gem 'aws-sdk-v1', '~> 1.67'
9
+ gem 'dotenv', '~> 2.2', '>= 2.2.1'
10
+ gem 'thor', '= 0.20.0'
11
+ gem 'activesupport', '~> 5.1', '>= 5.1.4'
12
+ gem 'byebug', '~> 10.0', '>= 10.0.2'
13
+ gem 'git', '~> 1.3'
14
14
 
15
- # Add dependencies to develop your gem here.
16
- # Include everything needed to run rake, tests, features, etc.
17
15
  group :development do
18
- gem "rspec"
19
- gem "rdoc", "~> 3.12"
20
- gem "bundler", "~> 1.0"
21
- gem "juwelier"
22
- gem "simplecov", ">= 0"
16
+ gem 'rspec', '~> 3.7'
17
+ gem 'rdoc', '~> 3.12'
18
+ gem 'bundler', '~> 2.0'
19
+ gem 'juwelier', '~> 2.4', '>= 2.4.7'
20
+ gem 'simplecov', '>= 0'
23
21
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.5.0
@@ -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.1.2 ruby lib
5
+ # stub: hashicorptools 0.5.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "hashicorptools".freeze
9
- s.version = "0.1.2"
9
+ s.version = "0.5.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 = "2017-08-21"
14
+ s.date = "2020-07-17"
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]
@@ -24,7 +24,6 @@ Gem::Specification.new do |s|
24
24
  ".ruby-version",
25
25
  ".travis.yml",
26
26
  "Gemfile",
27
- "Gemfile.lock",
28
27
  "LICENSE",
29
28
  "README.md",
30
29
  "Rakefile",
@@ -38,7 +37,6 @@ Gem::Specification.new do |s|
38
37
  "lib/hashicorptools/ec2_utilities.rb",
39
38
  "lib/hashicorptools/host.rb",
40
39
  "lib/hashicorptools/packer.rb",
41
- "lib/hashicorptools/terraform.rb",
42
40
  "lib/hashicorptools/update_launch_configuration.rb",
43
41
  "lib/hashicorptools/variables.rb",
44
42
  "spec/hashicorptools_spec.rb",
@@ -46,54 +44,40 @@ Gem::Specification.new do |s|
46
44
  ]
47
45
  s.homepage = "http://github.com/woodhull/hashicorptools".freeze
48
46
  s.licenses = ["MIT".freeze]
49
- s.rubygems_version = "2.5.2".freeze
47
+ s.rubygems_version = "3.1.2".freeze
50
48
  s.summary = "Wrappers for terraform and packer".freeze
51
49
 
52
50
  if s.respond_to? :specification_version then
53
51
  s.specification_version = 4
52
+ end
54
53
 
55
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
56
- s.add_runtime_dependency(%q<aws-sdk>.freeze, ["~> 2"])
57
- s.add_runtime_dependency(%q<dynect_rest>.freeze, [">= 0"])
58
- s.add_runtime_dependency(%q<aws-sdk-v1>.freeze, [">= 0"])
59
- s.add_runtime_dependency(%q<dotenv>.freeze, [">= 0"])
60
- s.add_runtime_dependency(%q<thor>.freeze, [">= 0"])
61
- s.add_runtime_dependency(%q<activesupport>.freeze, [">= 0"])
62
- s.add_runtime_dependency(%q<byebug>.freeze, [">= 0"])
63
- s.add_runtime_dependency(%q<git>.freeze, [">= 0"])
64
- s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
65
- s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
66
- s.add_development_dependency(%q<bundler>.freeze, ["~> 1.0"])
67
- s.add_development_dependency(%q<juwelier>.freeze, [">= 0"])
68
- s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
69
- else
70
- s.add_dependency(%q<aws-sdk>.freeze, ["~> 2"])
71
- s.add_dependency(%q<dynect_rest>.freeze, [">= 0"])
72
- s.add_dependency(%q<aws-sdk-v1>.freeze, [">= 0"])
73
- s.add_dependency(%q<dotenv>.freeze, [">= 0"])
74
- s.add_dependency(%q<thor>.freeze, [">= 0"])
75
- s.add_dependency(%q<activesupport>.freeze, [">= 0"])
76
- s.add_dependency(%q<byebug>.freeze, [">= 0"])
77
- s.add_dependency(%q<git>.freeze, [">= 0"])
78
- s.add_dependency(%q<rspec>.freeze, [">= 0"])
79
- s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
80
- s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
81
- s.add_dependency(%q<juwelier>.freeze, [">= 0"])
82
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
83
- 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<dynect_rest>.freeze, ["= 0.4.6"])
57
+ s.add_runtime_dependency(%q<aws-sdk-v1>.freeze, ["~> 1.67"])
58
+ s.add_runtime_dependency(%q<dotenv>.freeze, ["~> 2.2", ">= 2.2.1"])
59
+ s.add_runtime_dependency(%q<thor>.freeze, ["= 0.20.0"])
60
+ s.add_runtime_dependency(%q<activesupport>.freeze, ["~> 5.1", ">= 5.1.4"])
61
+ s.add_runtime_dependency(%q<byebug>.freeze, ["~> 10.0", ">= 10.0.2"])
62
+ s.add_runtime_dependency(%q<git>.freeze, ["~> 1.3"])
63
+ s.add_development_dependency(%q<rspec>.freeze, ["~> 3.7"])
64
+ s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
65
+ s.add_development_dependency(%q<bundler>.freeze, ["~> 2.0"])
66
+ s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.4", ">= 2.4.7"])
67
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
84
68
  else
85
69
  s.add_dependency(%q<aws-sdk>.freeze, ["~> 2"])
86
- s.add_dependency(%q<dynect_rest>.freeze, [">= 0"])
87
- s.add_dependency(%q<aws-sdk-v1>.freeze, [">= 0"])
88
- s.add_dependency(%q<dotenv>.freeze, [">= 0"])
89
- s.add_dependency(%q<thor>.freeze, [">= 0"])
90
- s.add_dependency(%q<activesupport>.freeze, [">= 0"])
91
- s.add_dependency(%q<byebug>.freeze, [">= 0"])
92
- s.add_dependency(%q<git>.freeze, [">= 0"])
93
- s.add_dependency(%q<rspec>.freeze, [">= 0"])
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", ">= 2.2.1"])
73
+ s.add_dependency(%q<thor>.freeze, ["= 0.20.0"])
74
+ s.add_dependency(%q<activesupport>.freeze, ["~> 5.1", ">= 5.1.4"])
75
+ s.add_dependency(%q<byebug>.freeze, ["~> 10.0", ">= 10.0.2"])
76
+ s.add_dependency(%q<git>.freeze, ["~> 1.3"])
77
+ s.add_dependency(%q<rspec>.freeze, ["~> 3.7"])
94
78
  s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
95
- s.add_dependency(%q<bundler>.freeze, ["~> 1.0"])
96
- s.add_dependency(%q<juwelier>.freeze, [">= 0"])
79
+ s.add_dependency(%q<bundler>.freeze, ["~> 2.0"])
80
+ s.add_dependency(%q<juwelier>.freeze, ["~> 2.4", ">= 2.4.7"])
97
81
  s.add_dependency(%q<simplecov>.freeze, [">= 0"])
98
82
  end
99
83
  end
@@ -13,7 +13,6 @@ require_relative 'hashicorptools/variables'
13
13
  require_relative 'hashicorptools/ec2_utilities'
14
14
  require_relative 'hashicorptools/auto_scaling_group'
15
15
  require_relative 'hashicorptools/packer'
16
- require_relative 'hashicorptools/terraform'
17
16
  require_relative 'hashicorptools/host'
18
17
  require_relative 'hashicorptools/update_launch_configuration'
19
18
  require_relative 'hashicorptools/code_deploy'
@@ -1,47 +1,60 @@
1
1
  {
2
- "variables": {
3
- "aws_access_key": "",
4
- "aws_secret_key": "",
5
- "source_ami": "",
6
- "ami_tag": "",
7
- "cookbook_name": ""
8
- },
9
-
10
2
  "builders": [
11
3
  {
12
- "type": "amazon-ebs",
13
4
  "access_key": "{{user `aws_access_key`}}",
14
- "secret_key": "{{user `aws_secret_key`}}",
5
+ "ami_name": "{{user `ami_tag`}} {{timestamp}}",
6
+ "associate_public_ip_address": true,
7
+ "ena_support": true,
8
+ "instance_type": "c5.large",
9
+ "launch_block_device_mappings": [
10
+ {
11
+ "delete_on_termination": true,
12
+ "device_name": "/dev/sda1",
13
+ "volume_size": 8,
14
+ "volume_type": "gp2"
15
+ }
16
+ ],
15
17
  "region": "us-east-1",
18
+ "ami_regions": ["us-east-1", "eu-central-1"],
19
+ "run_tags": {
20
+ "kind": "packer",
21
+ "role": "AMI builder"
22
+ },
23
+ "secret_key": "{{user `aws_secret_key`}}",
16
24
  "source_ami": "{{user `source_ami`}}",
17
- "instance_type": "c4.large",
25
+ "ssh_interface": "public_ip",
18
26
  "ssh_username": "ubuntu",
19
- "ami_name": "{{user `ami_tag`}} {{timestamp}}",
27
+ "subnet_id": "{{user `subnet_id`}}",
20
28
  "tags": {
21
29
  "Name": "{{user `ami_tag`}}",
22
30
  "created_at": "{{isotime}}",
23
31
  "parent_ami": "{{user `source_ami`}}"
24
32
  },
25
- "run_tags": {
26
- "kind": "packer",
27
- "role": "AMI builder"
28
- },
29
- "launch_block_device_mappings": [{
30
- "device_name": "/dev/sda1",
31
- "volume_size": 8,
32
- "volume_type": "gp2",
33
- "delete_on_termination": true
34
- }]
33
+ "type": "amazon-ebs",
34
+ "vpc_id": "{{user `vpc_id`}}"
35
35
  }
36
36
  ],
37
+ "post-processors": [],
37
38
  "provisioners": [
38
39
  {
39
- "type": "chef-solo",
40
- "cookbook_paths": ["cookbooks", "site-cookbooks"],
41
- "run_list": ["{{user `cookbook_name`}}"],
40
+ "cookbook_paths": [
41
+ "cookbooks",
42
+ "site-cookbooks"
43
+ ],
44
+ "run_list": [
45
+ "{{user `cookbook_name`}}"
46
+ ],
42
47
  "skip_install": true,
43
- "data_bags_path": "data_bags",
44
- "encrypted_data_bag_secret_path": "/etc/chef/encrypted_data_bag_secret"
48
+ "type": "chef-solo"
45
49
  }
46
- ]
50
+ ],
51
+ "variables": {
52
+ "ami_tag": "",
53
+ "aws_access_key": "",
54
+ "aws_secret_key": "",
55
+ "cookbook_name": "",
56
+ "source_ami": "",
57
+ "subnet_id": "",
58
+ "vpc_id": ""
59
+ }
47
60
  }
@@ -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|
@@ -24,12 +24,13 @@ module Hashicorptools
24
24
  end
25
25
 
26
26
  puts "waiting for scaling events to finish"
27
- groups.each do |group|
28
- wait_for_activities_to_complete(group)
27
+ wait_for_activities_to_complete(group)
28
+ puts "all scaling activities finished."
29
+
30
+ if desired_instances > 0
31
+ wait_until_instances_ready
32
+ puts "all #{desired_instances} instances ready."
29
33
  end
30
- puts "all #{desired_instances} scaling activities successful."
31
- wait_until_instances_ready
32
- puts "all #{desired_instances} instances ready."
33
34
  end
34
35
 
35
36
  def wait_until_instances_ready
@@ -89,6 +90,15 @@ module Hashicorptools
89
90
  end
90
91
  end
91
92
 
93
+ def verify_all_instances_using_correct_ami
94
+ launch_configuration = Aws::AutoScaling::LaunchConfiguration.new(name: group.launch_configuration_name, client: autoscaling)
95
+ image_id = launch_configuration.image_id
96
+ group.instances.each do |i|
97
+ instance = Aws::EC2::Instance.new(i.instance_id, client: ec2)
98
+ raise "#{i.instance_id} has the incorrect AMI, not #{image_id} from current LaunchConfig" if instance.image_id != image_id
99
+ end
100
+ end
101
+
92
102
  private
93
103
 
94
104
  def wait_for_activities_to_complete(group)
@@ -105,15 +115,15 @@ module Hashicorptools
105
115
  end
106
116
 
107
117
  def autoscaling
108
- @autoscaling ||= Aws::AutoScaling::Client.new(region: 'us-east-1')
118
+ @autoscaling ||= Aws::AutoScaling::Client.new(region: region)
109
119
  end
110
120
 
111
121
  def ec2
112
- @ec2 ||= Aws::EC2::Client.new(region: 'us-east-1')
122
+ @ec2 ||= Aws::EC2::Client.new(region: region)
113
123
  end
114
124
 
115
125
  def elb
116
- @elb ||= Aws::ElasticLoadBalancing::Client.new(region: 'us-east-1')
126
+ @elb ||= Aws::ElasticLoadBalancing::Client.new(region: region)
117
127
  end
118
128
 
119
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, :required => true
14
- option :branch, default: 'master'
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
- g.checkout(options[:branch].to_sym)
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 "deploying commit: #{commit.sha} #{commit.message}"
73
+ puts "Deploying for regions: #{aws_regions}"
28
74
 
29
- create_deployment(commit.sha, commit.message)
75
+ threads = []
76
+ aws_regions.each_slice(2) do |aws_regions_batch|
77
+ puts "Deploying for 2 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 create_deployment(commit_id, commit_message = nil)
35
- Dotenv.load
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 application_name
55
- raise "implement me"
100
+ def default_regions
101
+ [AWS_REGION_US_EAST_1]
56
102
  end
57
103
  end
58
104
  end