TerraformDevKit 0.1.10 → 0.1.11

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
2
  SHA1:
3
- metadata.gz: 4e92fbd82b70265947a9eb3db56bad0c5b85d78f
4
- data.tar.gz: 9048f6a2ea5e8ff08181d87515050ccf10e0931e
3
+ metadata.gz: 73056367038798386bcc02b1d20f801c27e43ef0
4
+ data.tar.gz: 0e1f59d12f2dd358ea463360bb3dce9e0f5255b0
5
5
  SHA512:
6
- metadata.gz: 1ebef969303e8fc2f00e1911a04990d3f3abbf790277f3a863788cdd57ea00bb848c25d5bdb346bd9a931375e3dcd7bbfbdb06a708a83067d950235d77ec6490
7
- data.tar.gz: 294017e43b6b007d2c0fc23e93ab7bbed995e65c011eaeda6062ca8a6381f28d1361575ce7cc2ff15e3175d292bd48b7a72570571786f925eccbf6ccf28cfb8b
6
+ metadata.gz: f61ca6d7b4d70b25298ea785c27245c0e59df4e8e41f8490ece88a33e6e9e900b7e048029bd2429d90b631d519fcf8aa04f1d27754d939a6927f27393609a75f
7
+ data.tar.gz: 5eef28470ca98ce7e859c20bae13cfc8f1baa4b9c362f2278bd406543c6f0358e80e6e935b04db9572b23679e79984a8c6a17eed01428d5a03dab888e50f80c0
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # TerraformDevKit
2
2
 
3
- [![Build Status](https://travis-ci.org/vistaprint/TerraformDevKit.svg?branch=master)](https://travis-ci.org/vistaprint/TerraformDevKit) [![Build status](https://ci.appveyor.com/api/projects/status/4vkyr196li83vju6/branch/master?svg=true)](https://ci.appveyor.com/project/betabandido/terraformdevkit/branch/master)
3
+ [![Build Status](https://travis-ci.org/vistaprint/TerraformDevKit.svg?branch=master)](https://travis-ci.org/vistaprint/TerraformDevKit) [![Build status](https://ci.appveyor.com/api/projects/status/74s4yd7dmuwg5tmn/branch/master?svg=true)](https://ci.appveyor.com/project/Vistaprint/terraformdevkit/branch/master)
4
4
 
5
5
  Set of scripts to ease development and testing with [Terraform](https://www.terraform.io/).
6
6
 
@@ -44,6 +44,108 @@ To use the library simply import it as:
44
44
  require 'TerraformDevKit'
45
45
  ```
46
46
 
47
+ ## Managing Terraform Environments
48
+
49
+ TerraformDevKit provides a set of Rake tasks and Ruby scripts to ease the management of multiple Terraform environments. Three major environment types are supported: `dev`, `test` and `prod`.
50
+
51
+ There might be many development environments (`dev`), each one with its own name. Development environments use a local Terraform backend. They are intented to be used by developers while adding features to the infrastructure.
52
+
53
+ Testing (`test`) and production (`prod`) environment use a remote backend. Thus, the Terraform state file is not kept in the local disk, but on S3. This allows multiple developers to easily work on the same infrastructure instance. For safety reasons, operations that affect testing and production environments require manual user input. This is not the case for development environments.
54
+
55
+ TerraformDevKit expects templated versions (using [Mustache](https://mustache.github.io/)) of the Terraform files. Such files might contain placeholders for several fields such as `Environment`, (AWS) `Region` or (AWS) `Profile`, among others. TerraformDevKit uses the template files to generate the final files that will be consumed by Terraform and Terragrunt. As an example, for the production environment, the resulting files are placed in a directory named `envs/prod`.
56
+
57
+ ### Configuration Files
58
+
59
+ Configuration files must be placed in a directory named `config`. Each environment type requires a different configuration file. Thus, the following three files must be placed in the `config` directory:
60
+
61
+ * `config-dev.yml`
62
+ * `config-test.yml`
63
+ * `config-prod.yml`
64
+
65
+ The first one contains the configuration for **all** the development environments that are created. The other two contain the configuration for the test and production environments, respectively.
66
+
67
+ A sample configuration files is shown next:
68
+
69
+ ```yaml
70
+ terraform-version: 0.10.8
71
+ terragrunt-version: 0.13.15
72
+ aws:
73
+ profile: myprofile
74
+ region: eu-west-1
75
+ ```
76
+
77
+ The AWS profile **must not** be specified for test and production accounts, as users are required to manually type the profile name.
78
+
79
+ ### A Minimal Rakefile
80
+
81
+ ```ruby
82
+ ROOT_PATH = File.dirname(File.expand_path(__FILE__))
83
+
84
+ spec = Gem::Specification.find_by_name 'TerraformDevKit'
85
+ load "#{spec.gem_dir}/tasks/devkit.rake"
86
+
87
+ task :custom_test, [:env] do |_, args|
88
+ # Add some tests here
89
+ end
90
+ ```
91
+
92
+ ### Sample Terraform/Terragrunt Templates
93
+
94
+ The following file (`main.tf.mustache`) contains the infrastructure configuration (a single S3 bucket) as well as information related to the AWS provider.
95
+
96
+ ```hcl
97
+ locals {
98
+ env = "{{Environment}}"
99
+ }
100
+
101
+ terraform {
102
+ backend {{#LocalBackend}}"local"{{/LocalBackend}}{{^LocalBackend}}"s3"{{/LocalBackend}} {}
103
+ }
104
+
105
+ provider "aws" {
106
+ profile = "{{Profile}}"
107
+ region = "{{Region}}"
108
+ }
109
+
110
+ resource "aws_s3_bucket" "raw" {
111
+ bucket = "foo-${local.env}"
112
+ acl = "private"
113
+
114
+ {{#LocalBackend}}
115
+ force_destroy = true
116
+ {{/LocalBackend}}
117
+ {{^LocalBackend}}
118
+ lifecycle {
119
+ prevent_destroy = true
120
+ }
121
+ {{/LocalBackend}}
122
+ }
123
+ ```
124
+
125
+ An additional file (`terraform.tfvars.mustache`) contains the Terragrunt configuration. Terragrunt is used as it makes it easier to manage a remote backend. While Terraform is able to keep the state file in S3, it does not transparently create the DynamoDB lock table that prevents multiple developers from concurrently modifying the state file. Terragrunt, however, is able to do this without user intervention.
126
+
127
+ ```hcl
128
+ terragrunt = {
129
+ remote_state {
130
+ {{#LocalBackend}}
131
+ backend = "local"
132
+ config {}
133
+ {{/LocalBackend}}
134
+ {{^LocalBackend}}
135
+ backend = "s3"
136
+ config {
137
+ bucket = "foo-remote-state"
138
+ key = "foo-{{Environment}}.tfstate"
139
+ lock_table = "foo-{{Environment}}-lock-table"
140
+ encrypt = true
141
+ profile = "{{Profile}}"
142
+ region = "{{Region}}"
143
+ }
144
+ {{/LocalBackend}}
145
+ }
146
+ }
147
+ ```
148
+
47
149
  ## Development
48
150
 
49
151
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -4,14 +4,20 @@ require 'fileutils'
4
4
 
5
5
  module TerraformDevKit
6
6
  class TerraformConfigManager
7
- def self.setup(env, extra_vars: {})
7
+ @extra_vars_proc = proc { {} }
8
+
9
+ def self.register_extra_vars_proc(p)
10
+ @extra_vars_proc = p
11
+ end
12
+
13
+ def self.setup(env)
8
14
  fix_configuration(env)
9
15
  create_environment_directory(env)
10
- render_template_config_files(env, extra_vars)
16
+ render_template_config_files(env)
11
17
  end
12
18
 
13
19
  def self.update_modules?
14
- skip_update = ENV.fetch('TF_DEV_KIT_SKIP_MODULE_UPDATE', 'false')
20
+ skip_update = ENV.fetch('TF_DEVKIT_SKIP_MODULE_UPDATE', 'false')
15
21
  .strip
16
22
  .downcase
17
23
  skip_update != 'true'
@@ -38,7 +44,7 @@ module TerraformDevKit
38
44
  end
39
45
 
40
46
  private_class_method
41
- def self.render_template_config_files(env, extra_vars)
47
+ def self.render_template_config_files(env)
42
48
  aws_config = Configuration.get('aws')
43
49
  file_list = Dir['*.tf.mustache'] + Dir['*.tfvars.mustache']
44
50
  file_list.each do |fname|
@@ -46,7 +52,7 @@ module TerraformDevKit
46
52
  File.read(fname),
47
53
  env,
48
54
  aws_config,
49
- extra_vars: extra_vars
55
+ extra_vars: @extra_vars_proc.call(env)
50
56
  )
51
57
  config_fname = File.basename(fname, File.extname(fname))
52
58
  Dir.chdir(env.working_dir) do
@@ -60,7 +66,7 @@ module TerraformDevKit
60
66
  puts "Environment #{env.name} requires manual input of AWS credentials"
61
67
  print 'Enter the profile to use: '
62
68
  profile = $stdin.gets.tr("\r\n", '')
63
- raise 'Invalid profile name' unless /^\w+$/ =~ profile
69
+ /^\w+$/ =~ profile || (raise 'Invalid profile name')
64
70
  profile
65
71
  end
66
72
  end
@@ -1,3 +1,3 @@
1
1
  module TerraformDevKit
2
- VERSION = '0.1.10'.freeze
2
+ VERSION = '0.1.11'.freeze
3
3
  end
data/tasks/devkit.rake CHANGED
@@ -12,8 +12,6 @@ ENV['PATH'] = TDK::OS.join_env_path(
12
12
  ENV['PATH']
13
13
  )
14
14
 
15
- TF_CONFIG_EXTRA_VARS = {}.freeze unless defined?(TF_CONFIG_EXTRA_VARS)
16
-
17
15
  def destroy_if_fails(env)
18
16
  yield
19
17
  rescue StandardError => e
@@ -41,17 +39,19 @@ task :prepare, [:env] do |_, args|
41
39
  directory: BIN_PATH
42
40
  )
43
41
 
44
- TDK::TerraformConfigManager.setup(env, extra_vars: TF_CONFIG_EXTRA_VARS)
42
+ TDK::TerraformConfigManager.setup(env)
45
43
 
46
- task('custom_prepare').invoke(args.env) if Rake::Task.task_defined?('custom_prepare')
44
+ if Rake::Task.task_defined?('custom_prepare')
45
+ task('custom_prepare').invoke(args.env)
46
+ end
47
47
 
48
48
  TDK::Command.run(
49
- 'terragrunt init',
49
+ 'terragrunt init -upgrade=false',
50
50
  directory: env.working_dir,
51
51
  close_stdin: false
52
52
  )
53
53
 
54
- cmd = 'terragrunt get'
54
+ cmd = 'terragrunt get'
55
55
  cmd += ' -update=true' if TDK::TerraformConfigManager.update_modules?
56
56
  TDK::Command.run(cmd, directory: env.working_dir)
57
57
  end
@@ -73,12 +73,14 @@ end
73
73
  desc 'Tests a local environment'
74
74
  task :test, [:env] do |_, args|
75
75
  env = TDK::Environment.new(args.env)
76
- raise 'Testing is only allowed for local environments' unless env.local_backend?
76
+ env.local_backend? || (raise 'Testing is only allowed for local environments')
77
77
 
78
78
  task('apply').invoke(env.name)
79
79
 
80
80
  destroy_if_fails(env) do
81
- task('custom_test').invoke(args.env) if Rake::Task.task_defined?('custom_test')
81
+ if Rake::Task.task_defined?('custom_test')
82
+ task('custom_test').invoke(args.env)
83
+ end
82
84
  end
83
85
  end
84
86
 
@@ -96,6 +98,9 @@ task :destroy, [:env] => :prepare do |_, args|
96
98
  cmd = 'terragrunt destroy'
97
99
  cmd += ' -force' if env.local_backend?
98
100
  TDK::Command.run(cmd, directory: env.working_dir, close_stdin: false)
101
+ if Rake::Task.task_defined?('custom_destroy')
102
+ task('custom_destroy').invoke(args.env)
103
+ end
99
104
  end
100
105
 
101
106
  desc 'Cleans an environment (infrastructure is destroyed too)'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: TerraformDevKit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Jimenez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-05 00:00:00.000000000 Z
11
+ date: 2017-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler