rake-terraform 0.0.3

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YmZiOTEzNThjZDlkMDU1MmQzOTJiMmNlMGFhY2E0ODg3ODdjMzQ1NA==
5
+ data.tar.gz: !binary |-
6
+ YWFlOWViNWExNTNkNDhiYTZiMTg3Mjg3NWQ1MTQ2ZTliMzEzMTFmNQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YmMzMDlhZTFiYmM0OGViOWRiYjYzZGYzMmI3YTA3Mjk4YjM4MTg1ZDQyZDU1
10
+ Y2M2M2ZmN2E3MzQyZjBhYWMyZjk1MDkyZDU5YmY1ZDY0YjdiMjk5MDhiNTNm
11
+ YzA3ZGVhMWQ0ZmZkODk1ZDU4NzA0N2FjZDJjYjU3ZWFiZjJkNjg=
12
+ data.tar.gz: !binary |-
13
+ NTA2NGYxNThhZDZlZmIzYmVlNGYwZDFhY2ZmNDVmZTIxMzI3YjYxMjc1YzZk
14
+ NDQ5OGIzMjQyYWEwYmY3NTc3ODc5YjE3ZDQ5OTIzYjZmYjBlZDY0MzcxMmM3
15
+ ZTQ1ZWJhNGNjYjhkMGMyMmViNDYxZDYyOWNjYTg1NGU3NzRiOTE=
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ terraform/
16
+ .idea/
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ deploy:
6
+ provider: rubygems
7
+ gem: rake-terraform
8
+ on:
9
+ tags: true
10
+ all_branches: true
11
+ api_key:
12
+ secure: hOaHuMk5/lcedaCiP/GkICXy+tNS6uHrrkizoFn4Tv5GhWoAao77e4FWuZh9KNSAmiZIQwPa1z5b9kn8Rq2UE0QjrxBYmDFFp5uM4fDl7xzqPXREfZcBNmrjMFUhXSRnyZnm4rC69lGRQKTSJkHZDAUZfWobFMnouMtRyoDSCbU=
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rake-terraform.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Norm MacLennan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,105 @@
1
+ # rake-terraform
2
+
3
+ [![Build Status](https://travis-ci.org/maclennann/rake-terraform.svg?branch=master)](https://travis-ci.org/maclennann/rake-terraform)
4
+ [![Code Climate](https://codeclimate.com/github/maclennann/rake-terraform/badges/gpa.svg)](https://codeclimate.com/github/maclennann/rake-terraform)
5
+ [![Test Coverage](https://codeclimate.com/github/maclennann/rake-terraform/badges/coverage.svg)](https://codeclimate.com/github/maclennann/rake-terraform)
6
+ [![Gem](https://img.shields.io/gem/dtv/rake-terraform.svg)]()
7
+
8
+ `rake-terraform` is a gem with a collection of rake tasks for working with [Hashicorp Terraform](https://terraform.io)
9
+ and terraform configuration files.
10
+
11
+ It provides tasks to calculate and execute plans based on a variety of file and module structures.
12
+
13
+ Note: This gem was specifically written for use with the AWS terraform provider. If you need to use another one,
14
+ please open an issue and/or file a pull request.
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ ```ruby
21
+ gem 'rake-terraform'
22
+ ```
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install rake-terraform
31
+
32
+ ## Usage
33
+
34
+ This gem currently provides two different types of tasks:
35
+
36
+ ### `terraform_plan`
37
+ This task can be used to calculate plans for a terraform configuration.
38
+
39
+ You can set the following configuration for the task:
40
+
41
+ * `t.input_dir` - the directory from which to read terraform config (default: `./terraform`)
42
+ * `t.output_file` - the path and name of the plan file to generate (default: `./output/terraform/plan.tf`)
43
+ * `t.credentials` - the path of the [AWS credentials file](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-config-files) to read from (default: `~/.aws/credentials`)
44
+ * `t.aws_project` - the name of the project to use from your credentials file (default: `default`)
45
+
46
+ ### `terraform_apply`
47
+ This task can be used to apply a calculated terraform plan.
48
+
49
+ You can set the following configuration for the task:
50
+
51
+ * `t.plan`: The name of the plan file to apply (default: `./output/terraform/plan.tf`)
52
+ * `t.execution_path`: The path from which to execute the plan (default: `./terraform`)
53
+ * This is useful if you are referencing cloud-config files using relative paths
54
+
55
+ To use these tasks, you should `require 'rake_terraform'` at the top of your Rakefile.
56
+
57
+ ### Default Tasks
58
+
59
+ This gem provides a `default_tasks` partial rakefile that should work for most use-cases.
60
+ It includes the concept of terraform 'environments'. This is useful for the AWS provider,
61
+ as terraform can only control one AWS region at a time. Which means a separate Terraform
62
+ configuration needs to be kept per region.
63
+
64
+ To use it, just `require 'rake-terraform/default_tasks'` at the top of your `Rakefile`.
65
+
66
+ Given, the following terraform hierarchy:
67
+ ```bash
68
+ terraform
69
+ us-east-1
70
+ main.tf
71
+ variables.tf
72
+ output.tf
73
+ us-west-1
74
+ main.tf
75
+ variables.tf
76
+ output.tf
77
+ ```
78
+
79
+ It wil automatically generate the following rake tasks:
80
+
81
+ ```bash
82
+ rake terraform:all # Plan and migrate all environments
83
+
84
+ rake terraform:apply_us-east-1 # Execute plan for us-east-1
85
+ rake terraform:apply_us-west-1 # Execute plan for us-west-1
86
+
87
+ rake terraform:plan_us-east-1 # Plan migration of us-east-1
88
+ rake terraform:plan_us-west-1 # Plan migration of us-west-1
89
+
90
+ rake terraform:us-east-1 # Plan and migrate us-east-1
91
+ rake terraform:us-west-1 # Plan and migrate us-west-1
92
+ ```
93
+
94
+ The following environment variables can be set to tweak `default_task`'s behavior:
95
+ * `ENV['TERRAFORM_AWS_PROJECT']` - Sets `t.aws_project` on the `terraform_plan` tasks (default: `default`)
96
+ * `ENV['TERRAFORM_ENVIRONMENT_GLOB']` - Dir glob used to discover terraform environments (default: `terraform/**/*.tf`)
97
+ * `ENV['TERRAFORM_OUTPUT_BASE']` - Directory to which plan files are saved/read. The environment name is appended to this automatically (default: `output/terraform`)
98
+
99
+ ## Contributing
100
+
101
+ 1. Fork it ( https://github.com/maclennann/rake-terraform/fork )
102
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
103
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
104
+ 4. Push to the branch (`git push origin my-new-feature`)
105
+ 5. Create a new Pull Request
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake-terraform/default_tasks'
3
+ require 'rubocop/rake_task'
4
+
5
+ task default: :rubocop
6
+
7
+ RuboCop::RakeTask.new
@@ -0,0 +1,31 @@
1
+ require 'rake_terraform'
2
+
3
+ namespace :terraform do
4
+ env_glob = ENV['TERRAFORM_ENVIRONMENT_GLOB'] || 'terraform/**/*.tf'
5
+ output_base = ENV['TERRAFORM_OUTPUT_BASE'] || 'output/terraform'
6
+ environments = (Dir.glob env_glob).map { |f| File.dirname f }.uniq
7
+
8
+ environments.each do |env|
9
+ short_name = File.basename env
10
+ plan_path = File.expand_path File.join(output_base, "#{short_name}.tf")
11
+
12
+ desc "Plan migration of #{short_name}"
13
+ terraform_plan "plan_#{short_name}" do |t|
14
+ t.input_dir = env
15
+ t.aws_project = ENV['TERRAFORM_AWS_PROJECT'] || 'default'
16
+ t.output_file = plan_path
17
+ end
18
+
19
+ desc "Execute plan for #{short_name}"
20
+ terraform_apply "apply_#{short_name}" do |t|
21
+ t.plan = plan_path
22
+ t.execution_path = env
23
+ end
24
+
25
+ desc "Plan and migrate #{short_name}"
26
+ task short_name => %W(plan_#{short_name} apply_#{short_name})
27
+ end
28
+
29
+ desc 'Plan and migrate all environments'
30
+ task all: environments.map { |e| File.basename e }.uniq
31
+ end
@@ -0,0 +1,29 @@
1
+ require 'rake'
2
+
3
+ # Rake terraform
4
+ module RakeTerraform
5
+ private
6
+
7
+ # Definitions of methods for custom rake tasks
8
+ module DSL
9
+ def terraform_plan(*args)
10
+ require 'rake-terraform/tasks/plantask'
11
+ Rake::Task.define_task(*args) do
12
+ c = RakeTerraform::PlanTask::Config.new
13
+ yield c
14
+ RakeTerraform::PlanTask::Task.new(c.opts).execute
15
+ end
16
+ end
17
+
18
+ def terraform_apply(*args)
19
+ require 'rake-terraform/tasks/applytask'
20
+ Rake::Task.define_task(*args) do
21
+ c = RakeTerraform::ApplyTask::Config.new
22
+ yield c
23
+ RakeTerraform::ApplyTask::Task.new(c.opts).execute
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ extend RakeTerraform::DSL
@@ -0,0 +1,55 @@
1
+ module RakeTerraform
2
+ module ApplyTask
3
+ # Configuration data for terraform apply task
4
+ class Config
5
+ attr_accessor :plan
6
+ attr_accessor :execution_path
7
+ def initialize
8
+ @plan = File.expand_path(default_plan)
9
+ @execution_path = File.expand_path 'terraform'
10
+ end
11
+
12
+ def opts
13
+ Map.new(plan: @plan,
14
+ execution_path: @execution_path)
15
+ end
16
+
17
+ private
18
+
19
+ def default_plan
20
+ File.join('output', 'terraform', 'plan.tf')
21
+ end
22
+ end
23
+
24
+ # Custom rake task to run `terraform apply`
25
+ class Task < BaseTask
26
+ def initialize(opts)
27
+ @opts = opts
28
+ end
29
+
30
+ def execute
31
+ require 'highline/import'
32
+
33
+ plan = @opts.get(:plan)
34
+ validate_terraform_installed
35
+ ensure_plan_exists plan
36
+
37
+ system "terraform show --module-depth=2 #{plan}"
38
+
39
+ say 'The above changes will be applied to your environment.'
40
+ exit unless agree 'Are you sure you want to execute this plan? (y/n)'
41
+
42
+ Dir.chdir(@opts.get(:execution_path)) do
43
+ system "terraform apply #{plan}"
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def ensure_plan_exists(plan)
50
+ require 'fileutils'
51
+ fail "Plan #{plan} does not exist! Aborting!" unless File.exist? plan
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ require 'rake/task'
2
+ require 'iniparse'
3
+ require 'English'
4
+
5
+ module RakeTerraform
6
+ # Methods that all tasks have in common
7
+ class BaseTask < Rake::Task
8
+ def validate_terraform_installed
9
+ error = 'Please ensure you have terraform installed and on your path!'
10
+ fail error unless terraform_installed?
11
+ end
12
+
13
+ def terraform_installed?
14
+ `terraform version`
15
+ $CHILD_STATUS.success?
16
+ rescue => _
17
+ false
18
+ end
19
+
20
+ def get_aws_credentials(creds_file, project = 'default')
21
+ error = "Could not locate AWS credentials in #{creds_file}!"
22
+ fail error unless File.exist? creds_file
23
+
24
+ credentials = IniParse.parse(File.read(creds_file))
25
+ { accesskey: credentials[project]['aws_access_key_id'],
26
+ secretkey: credentials[project]['aws_secret_access_key'] }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,87 @@
1
+ require 'rake/task'
2
+ require 'rake-terraform/tasks/basetask'
3
+ require 'map'
4
+
5
+ # Custom rake task to perform `terraform plan`
6
+ module RakeTerraform
7
+ module PlanTask
8
+ # Configuration data for terraform plan task
9
+ class Config
10
+ attr_accessor :input_dir
11
+ attr_accessor :output_file
12
+ attr_accessor :credentials
13
+ attr_accessor :aws_project
14
+
15
+ def initialize
16
+ @input_dir = File.expand_path 'terraform'
17
+ @output_file = File.expand_path(default_output)
18
+ @credentials = File.expand_path(default_credentials)
19
+ @aws_project = 'default'
20
+ end
21
+
22
+ def opts
23
+ Map.new(input_dir: @input_dir,
24
+ output_file: @output_file,
25
+ credentials: @credentials,
26
+ aws_project: @aws_project)
27
+ end
28
+
29
+ private
30
+
31
+ def default_output
32
+ File.join('output', 'terraform', 'plan.tf')
33
+ end
34
+
35
+ def default_credentials
36
+ File.join('~', '.aws', 'credentials')
37
+ end
38
+ end
39
+
40
+ # Custom rake task to run `terraform plan`
41
+ class Task < BaseTask
42
+ attr_accessor :creds_file
43
+
44
+ def initialize(opts)
45
+ @creds_file = opts.get(:credentials)
46
+ @opts = opts
47
+ end
48
+
49
+ def execute
50
+ validate_terraform_installed
51
+ ensure_output_directory
52
+
53
+ creds = get_aws_credentials(@creds_file, @opts.get(:aws_project))
54
+
55
+ Dir.chdir(@opts.get(:input_dir)) do
56
+ puts '=> Fetching modules...'
57
+ system('terraform get')
58
+
59
+ command = construct_command creds
60
+ puts "=> Generating plan for #{@opts.get(:input_dir)}..."
61
+ system(command)
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def construct_command(creds)
68
+ access_key = creds[:accesskey]
69
+ secret_key = creds[:secretkey]
70
+
71
+ command = 'terraform plan '
72
+ command << "-var access_key=\"#{access_key}\" "
73
+ command << "-var secret_key=\"#{secret_key}\" "
74
+ command << '-module-depth 2 '
75
+ command << "-out #{@opts.get(:output_file)}" if @opts.get(:output_file)
76
+
77
+ command
78
+ end
79
+
80
+ def ensure_output_directory
81
+ require 'fileutils'
82
+ dir = File.dirname @opts.get(:output_file)
83
+ FileUtils.mkdir_p dir unless File.exist? dir
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,4 @@
1
+ # Version of the gem
2
+ module RakeTerraform
3
+ VERSION = '0.0.3'
4
+ end
@@ -0,0 +1,6 @@
1
+ require 'rake-terraform/version'
2
+ require 'rake-terraform/dsl'
3
+
4
+ # Top-level module
5
+ module RakeTerraform
6
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rake-terraform/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rake-terraform'
8
+ spec.version = RakeTerraform::VERSION
9
+ spec.authors = ['Norm MacLennan']
10
+ spec.email = ['norm.maclennan@gmail.com']
11
+ spec.summary = 'Rake tasks for use with Terraform.'
12
+ spec.description = 'A collection of rake tasks that can
13
+ be used to plan, apply, and manage
14
+ configurations for Hashicorp Terraform.'
15
+
16
+ spec.homepage = 'https://github.com/maclennann/rake-terraform'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1'
25
+ spec.add_development_dependency 'rubocop', '~> 0.29'
26
+ spec.add_dependency 'rake', '~> 10.0'
27
+ spec.add_dependency 'map', '~> 6.5'
28
+ spec.add_runtime_dependency 'highline', '~> 1.7'
29
+ spec.add_runtime_dependency 'iniparse', '~> 1.3'
30
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake-terraform
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Norm MacLennan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.29'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.29'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: map
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '6.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '6.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: highline
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: iniparse
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ description: ! "A collection of rake tasks that can\n be used
98
+ to plan, apply, and manage\n configurations for Hashicorp
99
+ Terraform."
100
+ email:
101
+ - norm.maclennan@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - .gitignore
107
+ - .travis.yml
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - lib/rake-terraform/default_tasks.rb
113
+ - lib/rake-terraform/dsl.rb
114
+ - lib/rake-terraform/tasks/applytask.rb
115
+ - lib/rake-terraform/tasks/basetask.rb
116
+ - lib/rake-terraform/tasks/plantask.rb
117
+ - lib/rake-terraform/version.rb
118
+ - lib/rake_terraform.rb
119
+ - rake-terraform.gemspec
120
+ homepage: https://github.com/maclennann/rake-terraform
121
+ licenses:
122
+ - MIT
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 2.4.5
141
+ signing_key:
142
+ specification_version: 4
143
+ summary: Rake tasks for use with Terraform.
144
+ test_files: []