├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── lib ├── tfoutputs.rb └── tfoutputs │ ├── configurator │ ├── backends │ │ ├── file_state_configuration.rb │ │ └── s3_state_configuration.rb │ ├── state_configurator.rb │ ├── state_reader.rb │ └── version.rb │ └── tooling │ └── vcr_redacter.rb ├── spec ├── acceptance │ ├── resources │ │ ├── terraform.tfstate │ │ └── terraform_acceptance_array_of_hashes.tfstate │ ├── s3_state_configuration_acceptance_spec.rb │ ├── state_configurator_spec.rb │ └── tf_outputs_spec.rb ├── fixtures │ └── vcr_cassettes │ │ ├── e2e-test-array-of-hashes.yml │ │ ├── e2e-test-single-hash.yml │ │ ├── get_file_list_from_options.yml │ │ └── get_state_from_bucket.yml ├── spec_helper.rb ├── spec_helper_acceptance.rb └── unit │ ├── resources │ └── terraform.tfstate │ └── state_reader_spec.rb └── tfoutputs.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | .idea/ 11 | .DS_Store 12 | bin/ 13 | binaries/ 14 | vendor/ 15 | .ruby_version 16 | .ruby-version 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.3.2 4 | - 2.3.3 5 | - 2.3.4 6 | - 2.3.5 7 | - 2.3.6 8 | - 2.3.7 9 | - 2.3.8 10 | - 2.4.0 11 | - 2.4.1 12 | - 2.4.2 13 | - 2.4.3 14 | - 2.4.4 15 | - 2.4.5 16 | - 2.5.0 17 | - 2.5.1 18 | - 2.5.2 19 | - 2.5.3 20 | 21 | script: bundle exec rake spec 22 | env: 23 | - AWS_ACCESS_KEY=foo AWS_SECRET_ACCESS_KEY=bar 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Version 0.2.3 2 | This release includes: 3 | - AWS Credential profile support : [PR #7](https://github.com/jedops/ruby-tfoutputs/pull/7) - Thanks [@steakfest](https://github.com/steakfest) 4 | 5 | 6 | ## Version 0.2.2 7 | This release includes: 8 | - make :respond_to? public: [PR #5](https://github.com/jae2/ruby-tfoutputs/pull/5) - Thanks [@patdowney](https://github.com/patdowney) 9 | 10 | ## Version 0.2.1 11 | This release includes: 12 | - Fix backend loading: [PR #4](https://github.com/jae2/ruby-tfoutputs/pull/4) - Thanks [@patdowney](https://github.com/patdowney) 13 | 14 | ## Version 0.2.0 - BROKEN RELEASE 15 | 16 | This release includes: 17 | - Removal of activestate gem - [PR #2](https://github.com/jae2/ruby-tfoutputs/pull/2) Thanks [@patdowney](https://github.com/patdowney) 18 | - inclusion of respond_to? method - [PR #3](https://github.com/jae2/ruby-tfoutputs/pull/2) 19 | 20 | 21 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of 4 | fostering an open and welcoming community, we pledge to respect all people who 5 | contribute through reporting issues, posting feature requests, updating 6 | documentation, submitting pull requests or patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free 9 | experience for everyone, regardless of level of experience, gender, gender 10 | identity and expression, sexual orientation, disability, personal appearance, 11 | body size, race, ethnicity, age, religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic 20 | addresses, without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or 24 | reject comments, commits, code, wiki edits, issues, and other contributions 25 | that are not aligned to this Code of Conduct, or to ban temporarily or 26 | permanently any contributor for other behaviors that they deem inappropriate, 27 | threatening, offensive, or harmful. 28 | 29 | By adopting this Code of Conduct, project maintainers commit themselves to 30 | fairly and consistently applying these principles to every aspect of managing 31 | this project. Project maintainers who do not follow or enforce the Code of 32 | Conduct may be permanently removed from the project team. 33 | 34 | This code of conduct applies both within project spaces and in public spaces 35 | when an individual is representing the project or its community. 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 38 | reported by contacting a project maintainer at admin@jaetech.org. All 39 | complaints will be reviewed and investigated and will result in a response that 40 | is deemed necessary and appropriate to the circumstances. Maintainers are 41 | obligated to maintain confidentiality with regard to the reporter of an 42 | incident. 43 | 44 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 45 | version 1.3.0, available at 46 | [http://contributor-covenant.org/version/1/3/0/][version] 47 | 48 | [homepage]: http://contributor-covenant.org 49 | [version]: http://contributor-covenant.org/version/1/3/0/ -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in tfoutputs-configurator.gemspec 4 | 5 | gemspec 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 James Edwards 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | ____ __ ____________ ____ __ __ 3 | / __ \__ __/ /_ __ __ /_ __/ ____/ / __ \__ __/ /_____ __ __/ /______ 4 | / /_/ / / / / __ \/ / / / / / / /_ / / / / / / / __/ __ \/ / / / __/ ___/ 5 | / _, _/ /_/ / /_/ / /_/ / / / / __/ / /_/ / /_/ / /_/ /_/ / /_/ / /_(__ ) 6 | /_/ |_|\__,_/_.___/\__, / /_/ /_/ \____/\__,_/\__/ .___/\__,_/\__/____/ 7 | /____/ /_/ 8 | ``` 9 | [![Build Status](https://travis-ci.org/jae2/ruby-tfoutputs.svg?branch=master)](https://travis-ci.org/jae2/ruby-tfoutputs) [![Gem Version](https://badge.fury.io/rb/tfoutputs.svg)](https://badge.fury.io/rb/tfoutputs) 10 | 11 | 12 | # Ruby TF Outputs 13 | 14 | This gem is a ruby interface to access your terraform outputs. 15 | 16 | ## Installation 17 | 18 | Add this line to your application's Gemfile: 19 | 20 | ```ruby 21 | gem 'tfoutputs' 22 | ``` 23 | 24 | And then execute: 25 | 26 | $ bundle 27 | 28 | Or install it yourself as: 29 | 30 | $ gem install tfoutputs 31 | 32 | 33 | 34 | 35 | ## Pre-requistes 36 | 37 | Ruby >= 2.2.2 38 | Your terraform state file also needs to be generated by terraform > 0.7.0 there are currently no plans to support terraform < 0.7.0 39 | 40 | 41 | 42 | ## Usage 43 | 44 | Require the gem: 45 | 46 | ```ruby 47 | require 'tfoutputs' 48 | ``` 49 | 50 | tfoutputs uses 'backends' as a means of retrieving the state files. A backend is a place where the terraform state file lives. Currently only two are supported: s3 and file. 51 | 52 | Setting up an s3 backend: 53 | 54 | ```ruby 55 | config = {:backend => 's3',:options => {:bucket_name => 'my-bucket-name-goes-here', 56 | :bucket_region => 'eu-west-1', :bucket_key => 'terraform.tfstate' } 57 | } 58 | state_reader = TfOutputs.configure(config) 59 | puts(state_reader.my_output_name) 60 | ``` 61 | 62 | S3 backends also have the following optional parameters: 63 | 64 | **profile** - The AWS Credential profile to use. 65 | 66 | Setting up a file backend: 67 | ```ruby 68 | config = {:backend => 'file', :options => { :file_path => '/path/to/state/file/terraform.tfstate' } } 69 | state_reader = TfOutputs.configure(config) 70 | puts(state_reader.my_output_name) 71 | 72 | ``` 73 | 74 | 75 | Using multiple states with multiple backends: 76 | 77 | ```ruby 78 | config = [{:backend => 's3',:options => {:bucket_name => 'my-bucket-name-goes-here', 79 | :bucket_region => 'eu-west-1', :bucket_key => 'terraform.tfstate' } 80 | }, 81 | {:backend => 'file', :options => { :file_path => '/path/to/state/file/terraform.tfstate' } } 82 | ] 83 | state_reader = TfOutputs.configure(config) 84 | puts(state_reader.my_output_name) 85 | ``` 86 | 87 | [Blog post on tfoutputs](https://jaetech.org/terraform-outputs-in-ruby/) 88 | 89 | 90 | ## Contributing 91 | 92 | Bug reports and pull requests are welcome on GitHub at https://github.com/jae2/ruby-tfoutput. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. 93 | 94 | 95 | ## License 96 | 97 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 98 | 99 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'rake' 3 | require 'rspec/core/rake_task' 4 | require 'tfoutputs/tooling/vcr_redacter' 5 | 6 | RSpec::Core::RakeTask.new(:spec) do |t| 7 | t.pattern = Dir.glob('spec/**/*_spec.rb') 8 | end 9 | 10 | task :rubocop do 11 | sh('rubocop') 12 | end 13 | 14 | def redact(dir) 15 | # Remove some but NOT necessarily all sensitive data from the VCR cassettes 16 | vcr_redacter = VCRRedacter.new 17 | puts("redacting: #{dir}") 18 | vcr_redacter.redact(dir) 19 | end 20 | 21 | at_exit do 22 | unless redact(Dir.pwd + '/spec/fixtures/vcr_cassettes') == 0 23 | raise('WARNING: VCR CASSETTES MAY NOT HAVE BEEN REDACTED INVESTIGATE BEFORE PUSHING CHANGES') 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/tfoutputs.rb: -------------------------------------------------------------------------------- 1 | require 'tfoutputs/configurator/version' 2 | require 'tfoutputs/configurator/state_configurator' 3 | require 'tfoutputs/configurator/state_reader' 4 | 5 | # Expect a list of files and options: 6 | 7 | module TfOutputs 8 | def configure(options) 9 | if options.is_a?(Hash) 10 | file_list = TfOutputs::Configurator::StateConfigurator.new([options]).file_list 11 | end 12 | file_list ||= TfOutputs::Configurator::StateConfigurator.new(options).file_list 13 | TfOutputs::Configurator::StateReader.new(file_list) 14 | end 15 | module_function :configure 16 | end 17 | -------------------------------------------------------------------------------- /lib/tfoutputs/configurator/backends/file_state_configuration.rb: -------------------------------------------------------------------------------- 1 | module TfOutputs 2 | module Configurator 3 | module Backends 4 | class FileStateConfiguration 5 | def initialize(options) 6 | @options = options 7 | end 8 | 9 | def save 10 | File.new (@options[:file_path]) 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/tfoutputs/configurator/backends/s3_state_configuration.rb: -------------------------------------------------------------------------------- 1 | require 'aws-sdk-s3' 2 | require 'tempfile' 3 | 4 | module TfOutputs 5 | module Configurator 6 | module Backends 7 | class S3StateConfiguration 8 | :attr_accessor 9 | def initialize(options) 10 | @bucket_name = options[:bucket_name] 11 | @bucket_key = options[:bucket_key] 12 | @bucket_region = options[:bucket_region] 13 | @profile = options[:profile] ? options[:profile] : nil 14 | end 15 | 16 | def save 17 | file = Tempfile.new('tf_state') 18 | 19 | # Setup the base client config which must always have a bucket region 20 | client_config = {region: @bucket_region} 21 | # if a profile was supplied, then add that to the client config 22 | if !@profile.nil? 23 | client_config[:profile] = @profile 24 | end 25 | 26 | # setup s3 client 27 | s3 = Aws::S3::Client.new(client_config) 28 | resp = s3.get_object bucket: @bucket_name, key: @bucket_key 29 | file.write(resp.body.string) 30 | file.rewind 31 | file 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/tfoutputs/configurator/state_configurator.rb: -------------------------------------------------------------------------------- 1 | module TfOutputs 2 | module Configurator 3 | class StateConfigurator 4 | attr_accessor :state_uris 5 | 6 | BACKENDS = { s3: 'S3StateConfiguration', 7 | file: 'FileStateConfiguration' }.freeze 8 | 9 | Dir.glob("#{File.dirname(__FILE__)}/backends/*").each do |filename| 10 | require_relative "backends/#{File.basename(filename)}" 11 | end 12 | 13 | def initialize(states_array) 14 | @states_array = states_array 15 | end 16 | 17 | def file_list 18 | file_list = [] 19 | @states_array.each do |state_hash| 20 | backend_name = state_hash[:backend] 21 | class_name = BACKENDS[backend_name.to_sym] 22 | clazz = Object.const_get("TfOutputs::Configurator::Backends::#{class_name}") 23 | state = clazz.new (state_hash[:options]) 24 | file_list.push(state.save) 25 | end 26 | file_list 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/tfoutputs/configurator/state_reader.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | module TfOutputs 4 | module Configurator 5 | class StateReader 6 | attr_accessor :file_paths, :outputs 7 | 8 | def initialize(file_paths) 9 | @file_paths = file_paths 10 | @outputs = [] 11 | get_outputs_from_file 12 | self 13 | end 14 | 15 | def respond_to? (method, include_private = false) 16 | outputs.each do |output| 17 | next unless output.keys[0] == method.to_s 18 | return true 19 | end 20 | super 21 | end 22 | 23 | protected 24 | def get_outputs_from_file 25 | @file_paths.each do |path, _use_sensitive| 26 | parser = JSON.parse(File.read(path)) 27 | parser['modules'].each do |tf_module| 28 | parse_outputs(tf_module) 29 | end 30 | end 31 | end 32 | 33 | protected 34 | def parse_outputs(tf_module) 35 | if tf_module['path'] == ['root'] 36 | tf_module['outputs'].collect do |k, v| 37 | @outputs.each { |output| raise "Duplicate key found #{k}" if output.key?(k) } 38 | @outputs.push(k => v) 39 | end 40 | end 41 | end 42 | 43 | def method_missing(name, *args, &block) 44 | # Hack - really we should call respond_to? 45 | outputs.each do |output| 46 | next unless output.keys[0] == name.to_s 47 | return 'sensitive' if output[name.to_s]['sensitive'] 48 | return output[name.to_s]['value'] 49 | end 50 | super(name, *args, &block) 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/tfoutputs/configurator/version.rb: -------------------------------------------------------------------------------- 1 | module TfOutputs 2 | module Configurator 3 | VERSION = '0.2.4'.freeze 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/tfoutputs/tooling/vcr_redacter.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | 3 | class VCRRedacter 4 | # Goes through every file in directory, looks for yaml files, attempt to parse and remove the AWS access keys from them. 5 | def redact(path) 6 | return 1 if !Dir.exist?(path) || Dir[path + '/*.yml'].empty? 7 | Dir.glob(path + '/*.yml') do |yml_file| 8 | file = YAML.load_file(yml_file) 9 | redacted = { 'Authorization' => ['redacted'] } 10 | file['http_interactions'].first['request']['headers'] = redacted 11 | File.open(yml_file, 'w') { |f| YAML.dump(file, f) } 12 | end 13 | 0 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/acceptance/resources/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "terraform_version": "0.7.0", 4 | "serial": 9, 5 | "lineage": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa", 6 | "modules": [ 7 | { 8 | "path": [ 9 | "root" 10 | ], 11 | "outputs": { 12 | "allowed_ips": { 13 | "sensitive": false, 14 | "type": "string", 15 | "value": "10.5.1.6/32" 16 | }, 17 | "api_resource_pool": { 18 | "sensitive": false, 19 | "type": "string", 20 | "value": "medium" 21 | }, 22 | "api_z1_count": { 23 | "sensitive": false, 24 | "type": "string", 25 | "value": "1" 26 | }, 27 | "api_z2_count": { 28 | "sensitive": false, 29 | "type": "string", 30 | "value": "0" 31 | }, 32 | "aws_region": { 33 | "sensitive": false, 34 | "type": "string", 35 | "value": "eu-west-1" 36 | }, 37 | "backbone_resource_pool": { 38 | "sensitive": false, 39 | "type": "string", 40 | "value": "large" 41 | }, 42 | "backbone_z1_count": { 43 | "sensitive": false, 44 | "type": "string", 45 | "value": "1" 46 | }, 47 | "backbone_z2_count": { 48 | "sensitive": false, 49 | "type": "string", 50 | "value": "0" 51 | }, 52 | "cf_admin_pass": { 53 | "sensitive": true, 54 | "type": "string", 55 | "value": "notarealpass" 56 | }, 57 | "cf_apps_subdomain": { 58 | "sensitive": false, 59 | "type": "string", 60 | "value": "apps" 61 | }, 62 | "cf_boshworkspace_version": { 63 | "sensitive": false, 64 | "type": "string", 65 | "value": "v1.2.0" 66 | }, 67 | "cf_domain": { 68 | "sensitive": false, 69 | "type": "string", 70 | "value": "XIP" 71 | }, 72 | "cf_release_version": { 73 | "sensitive": false, 74 | "type": "string", 75 | "value": "222" 76 | }, 77 | "cf_run_subdomain": { 78 | "sensitive": false, 79 | "type": "string", 80 | "value": "run" 81 | }, 82 | "cf_size": { 83 | "sensitive": false, 84 | "type": "string", 85 | "value": "tiny" 86 | }, 87 | "data_resource_pool": { 88 | "sensitive": false, 89 | "type": "string", 90 | "value": "large" 91 | }, 92 | "debug": { 93 | "sensitive": false, 94 | "type": "string", 95 | "value": "false" 96 | }, 97 | "health_resource_pool": { 98 | "sensitive": false, 99 | "type": "string", 100 | "value": "medium" 101 | }, 102 | "health_z1_count": { 103 | "sensitive": false, 104 | "type": "string", 105 | "value": "1" 106 | }, 107 | "health_z2_count": { 108 | "sensitive": false, 109 | "type": "string", 110 | "value": "0" 111 | }, 112 | "install_docker_services": { 113 | "sensitive": false, 114 | "type": "string", 115 | "value": "false" 116 | }, 117 | "install_logsearch": { 118 | "sensitive": false, 119 | "type": "string", 120 | "value": "false" 121 | }, 122 | "ipmask": { 123 | "sensitive": false, 124 | "type": "string", 125 | "value": "10.10" 126 | }, 127 | "private_cf_domains": { 128 | "sensitive": false, 129 | "type": "string", 130 | "value": "" 131 | }, 132 | "private_haproxy_resource_pool": { 133 | "sensitive": false, 134 | "type": "string", 135 | "value": "small" 136 | }, 137 | "public_haproxy_resource_pool": { 138 | "sensitive": false, 139 | "type": "string", 140 | "value": "small" 141 | }, 142 | "runner_resource_pool": { 143 | "sensitive": false, 144 | "type": "string", 145 | "value": "runner" 146 | }, 147 | "runner_z1_count": { 148 | "sensitive": false, 149 | "type": "string", 150 | "value": "1" 151 | }, 152 | "runner_z2_count": { 153 | "sensitive": false, 154 | "type": "string", 155 | "value": "0" 156 | }, 157 | "services_resource_pool": { 158 | "sensitive": false, 159 | "type": "string", 160 | "value": "medium" 161 | }, 162 | "services_z1_count": { 163 | "sensitive": false, 164 | "type": "string", 165 | "value": "1" 166 | }, 167 | "services_z2_count": { 168 | "sensitive": false, 169 | "type": "string", 170 | "value": "0" 171 | } 172 | }, 173 | "resources": {} 174 | }, 175 | { 176 | "path": [ 177 | "root", 178 | "cf-net" 179 | ], 180 | "outputs": { 181 | "aws_subnet_lb_availability_zone": { 182 | "sensitive": false, 183 | "type": "string", 184 | "value": "eu-west-1a" 185 | } 186 | }, 187 | "resources": {} 188 | }, 189 | { 190 | "path": [ 191 | "root", 192 | "vpc" 193 | ], 194 | "outputs": {}, 195 | "resources": {} 196 | } 197 | ] 198 | } 199 | 200 | -------------------------------------------------------------------------------- /spec/acceptance/resources/terraform_acceptance_array_of_hashes.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "terraform_version": "0.7.0", 4 | "serial": 9, 5 | "lineage": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", 6 | "modules": [ 7 | { 8 | "path": [ 9 | "root" 10 | ], 11 | "outputs": { 12 | 13 | "services_z2_count_2": { 14 | "sensitive": false, 15 | "type": "string", 16 | "value": "it works" 17 | } 18 | }, 19 | "resources": {} 20 | }, 21 | { 22 | "path": [ 23 | "root", 24 | "cf-net" 25 | ], 26 | "outputs": { 27 | "aws_subnet_lb_availability_zone": { 28 | "sensitive": false, 29 | "type": "string", 30 | "value": "eu-west-1a" 31 | } 32 | }, 33 | "resources": {} 34 | }, 35 | { 36 | "path": [ 37 | "root", 38 | "vpc" 39 | ], 40 | "outputs": {}, 41 | "resources": {} 42 | } 43 | ] 44 | } 45 | 46 | -------------------------------------------------------------------------------- /spec/acceptance/s3_state_configuration_acceptance_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper_acceptance' 2 | 3 | describe 'state reader' do 4 | before(:each) do 5 | @s3_state_configuration = TfOutputs::Configurator::Backends::S3StateConfiguration.new(bucket_name: 'bucket-for-tf-configuration-tests', 6 | bucket_region: 'eu-west-1', 7 | bucket_key: 'this-is-a-test.json') 8 | end 9 | it 'should get bucket state file' do 10 | VCR.use_cassette('get_state_from_bucket') do 11 | @s3_state_configuration.save 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/acceptance/state_configurator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'state reader' do 4 | before(:each) do 5 | cwd = File.expand_path(File.dirname(__FILE__)) 6 | @tf_state = "#{cwd}/resources/terraform.tfstate" 7 | @sc = TfOutputs::Configurator::StateConfigurator.new([{ backend: 'file', options: { file_path: @tf_state } }, 8 | { backend: 's3', options: { bucket_name: 'bucket-for-tf-configuration-tests', 9 | bucket_region: 'eu-west-1', bucket_key: 'this-is-a-test.json' } }]) 10 | end 11 | it 'should return file list with options' do 12 | VCR.use_cassette('get_file_list_from_options') do 13 | @sc.file_list.each do |file| 14 | expect(file).to be_an_instance_of(File).or be_an_instance_of(Tempfile) 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/acceptance/tf_outputs_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper_acceptance' 2 | 3 | describe 'state reader' do 4 | before(:each) do 5 | @config = { backend: 's3', options: { bucket_name: 'bucket-for-tf-configuration-tests', 6 | bucket_region: 'eu-west-1', bucket_key: 'terraform.tfstate' } } 7 | end 8 | it 'should just bloody work' do 9 | VCR.use_cassette('e2e-test-single-hash') do 10 | sc = TfOutputs.configure(@config) 11 | expect(sc.cf_size).to eq('tiny') 12 | end 13 | end 14 | 15 | it 'should just bloody work with multiple array values' do 16 | VCR.use_cassette('e2e-test-array-of-hashes') do 17 | cwd = File.expand_path(File.dirname(__FILE__)) 18 | tf_state = "#{cwd}/resources/terraform_acceptance_array_of_hashes.tfstate" 19 | config_array = [ 20 | { backend: 's3', options: { bucket_name: 'bucket-for-tf-configuration-tests', 21 | bucket_region: 'eu-west-1', bucket_key: 'terraform.tfstate' } }, 22 | { backend: 'file', options: { file_path: tf_state } } 23 | ] 24 | sc = TfOutputs.configure(config_array) 25 | expect(sc.cf_size).to eq('tiny') 26 | expect(sc.services_z2_count_2).to eq('it works') 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/e2e-test-array-of-hashes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://bucket-for-tf-configuration-tests.s3.eu-west-1.amazonaws.com/terraform.tfstate 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | Authorization: 11 | - redacted 12 | response: 13 | status: 14 | code: 200 15 | message: OK 16 | headers: 17 | X-Amz-Id-2: 18 | - oWS9ucwoq69y/QKxkaReUpFu9QIj/Ene2UZUu++6ays1bZ7P7nRVrzaT0O+zIYkPYJEy94jlDaQ= 19 | X-Amz-Request-Id: 20 | - BB11D4D88FB3AE03 21 | Date: 22 | - Sun, 03 Jun 2018 14:24:44 GMT 23 | Last-Modified: 24 | - Wed, 19 Oct 2016 15:44:53 GMT 25 | Etag: 26 | - '"80215e4ab2c7b004bfb6b74d303491e0"' 27 | Accept-Ranges: 28 | - bytes 29 | Content-Type: 30 | - application/octet-stream 31 | Content-Length: 32 | - '6305' 33 | Server: 34 | - AmazonS3 35 | body: 36 | encoding: UTF-8 37 | string: |+ 38 | { 39 | "version": 3, 40 | "terraform_version": "0.7.0", 41 | "serial": 9, 42 | "lineage": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa", 43 | "modules": [ 44 | { 45 | "path": [ 46 | "root" 47 | ], 48 | "outputs": { 49 | "allowed_ips": { 50 | "sensitive": false, 51 | "type": "string", 52 | "value": "10.5.1.6/32" 53 | }, 54 | "api_resource_pool": { 55 | "sensitive": false, 56 | "type": "string", 57 | "value": "medium" 58 | }, 59 | "api_z1_count": { 60 | "sensitive": false, 61 | "type": "string", 62 | "value": "1" 63 | }, 64 | "api_z2_count": { 65 | "sensitive": false, 66 | "type": "string", 67 | "value": "0" 68 | }, 69 | "aws_region": { 70 | "sensitive": false, 71 | "type": "string", 72 | "value": "eu-west-1" 73 | }, 74 | "backbone_resource_pool": { 75 | "sensitive": false, 76 | "type": "string", 77 | "value": "large" 78 | }, 79 | "backbone_z1_count": { 80 | "sensitive": false, 81 | "type": "string", 82 | "value": "1" 83 | }, 84 | "backbone_z2_count": { 85 | "sensitive": false, 86 | "type": "string", 87 | "value": "0" 88 | }, 89 | "cf_admin_pass": { 90 | "sensitive": true, 91 | "type": "string", 92 | "value": "notarealpass" 93 | }, 94 | "cf_apps_subdomain": { 95 | "sensitive": false, 96 | "type": "string", 97 | "value": "apps" 98 | }, 99 | "cf_boshworkspace_version": { 100 | "sensitive": false, 101 | "type": "string", 102 | "value": "v1.2.0" 103 | }, 104 | "cf_domain": { 105 | "sensitive": false, 106 | "type": "string", 107 | "value": "XIP" 108 | }, 109 | "cf_release_version": { 110 | "sensitive": false, 111 | "type": "string", 112 | "value": "222" 113 | }, 114 | "cf_run_subdomain": { 115 | "sensitive": false, 116 | "type": "string", 117 | "value": "run" 118 | }, 119 | "cf_size": { 120 | "sensitive": false, 121 | "type": "string", 122 | "value": "tiny" 123 | }, 124 | "data_resource_pool": { 125 | "sensitive": false, 126 | "type": "string", 127 | "value": "large" 128 | }, 129 | "debug": { 130 | "sensitive": false, 131 | "type": "string", 132 | "value": "false" 133 | }, 134 | "health_resource_pool": { 135 | "sensitive": false, 136 | "type": "string", 137 | "value": "medium" 138 | }, 139 | "health_z1_count": { 140 | "sensitive": false, 141 | "type": "string", 142 | "value": "1" 143 | }, 144 | "health_z2_count": { 145 | "sensitive": false, 146 | "type": "string", 147 | "value": "0" 148 | }, 149 | "install_docker_services": { 150 | "sensitive": false, 151 | "type": "string", 152 | "value": "false" 153 | }, 154 | "install_logsearch": { 155 | "sensitive": false, 156 | "type": "string", 157 | "value": "false" 158 | }, 159 | "ipmask": { 160 | "sensitive": false, 161 | "type": "string", 162 | "value": "10.10" 163 | }, 164 | "private_cf_domains": { 165 | "sensitive": false, 166 | "type": "string", 167 | "value": "" 168 | }, 169 | "private_haproxy_resource_pool": { 170 | "sensitive": false, 171 | "type": "string", 172 | "value": "small" 173 | }, 174 | "public_haproxy_resource_pool": { 175 | "sensitive": false, 176 | "type": "string", 177 | "value": "small" 178 | }, 179 | "runner_resource_pool": { 180 | "sensitive": false, 181 | "type": "string", 182 | "value": "runner" 183 | }, 184 | "runner_z1_count": { 185 | "sensitive": false, 186 | "type": "string", 187 | "value": "1" 188 | }, 189 | "runner_z2_count": { 190 | "sensitive": false, 191 | "type": "string", 192 | "value": "0" 193 | }, 194 | "services_resource_pool": { 195 | "sensitive": false, 196 | "type": "string", 197 | "value": "medium" 198 | }, 199 | "services_z1_count": { 200 | "sensitive": false, 201 | "type": "string", 202 | "value": "1" 203 | }, 204 | "services_z2_count": { 205 | "sensitive": false, 206 | "type": "string", 207 | "value": "0" 208 | } 209 | }, 210 | "resources": {} 211 | }, 212 | { 213 | "path": [ 214 | "root", 215 | "cf-net" 216 | ], 217 | "outputs": { 218 | "aws_subnet_lb_availability_zone": { 219 | "sensitive": false, 220 | "type": "string", 221 | "value": "eu-west-1a" 222 | } 223 | }, 224 | "resources": {} 225 | }, 226 | { 227 | "path": [ 228 | "root", 229 | "vpc" 230 | ], 231 | "outputs": {}, 232 | "resources": {} 233 | } 234 | ] 235 | } 236 | 237 | http_version: 238 | recorded_at: Sun, 03 Jun 2018 14:24:43 GMT 239 | recorded_with: VCR 3.0.3 240 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/e2e-test-single-hash.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://bucket-for-tf-configuration-tests.s3.eu-west-1.amazonaws.com/terraform.tfstate 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | Authorization: 11 | - redacted 12 | response: 13 | status: 14 | code: 200 15 | message: OK 16 | headers: 17 | X-Amz-Id-2: 18 | - RhXJrdGxLIsaV1ll/huvVXAaUFVufGuwpujIi8EX53qSOMcZrAwplcffkTe983SzJvxV0a1m/u4= 19 | X-Amz-Request-Id: 20 | - 73721165DDDF911D 21 | Date: 22 | - Sun, 03 Jun 2018 14:24:44 GMT 23 | Last-Modified: 24 | - Wed, 19 Oct 2016 15:44:53 GMT 25 | Etag: 26 | - '"80215e4ab2c7b004bfb6b74d303491e0"' 27 | Accept-Ranges: 28 | - bytes 29 | Content-Type: 30 | - application/octet-stream 31 | Content-Length: 32 | - '6305' 33 | Server: 34 | - AmazonS3 35 | body: 36 | encoding: UTF-8 37 | string: |+ 38 | { 39 | "version": 3, 40 | "terraform_version": "0.7.0", 41 | "serial": 9, 42 | "lineage": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa", 43 | "modules": [ 44 | { 45 | "path": [ 46 | "root" 47 | ], 48 | "outputs": { 49 | "allowed_ips": { 50 | "sensitive": false, 51 | "type": "string", 52 | "value": "10.5.1.6/32" 53 | }, 54 | "api_resource_pool": { 55 | "sensitive": false, 56 | "type": "string", 57 | "value": "medium" 58 | }, 59 | "api_z1_count": { 60 | "sensitive": false, 61 | "type": "string", 62 | "value": "1" 63 | }, 64 | "api_z2_count": { 65 | "sensitive": false, 66 | "type": "string", 67 | "value": "0" 68 | }, 69 | "aws_region": { 70 | "sensitive": false, 71 | "type": "string", 72 | "value": "eu-west-1" 73 | }, 74 | "backbone_resource_pool": { 75 | "sensitive": false, 76 | "type": "string", 77 | "value": "large" 78 | }, 79 | "backbone_z1_count": { 80 | "sensitive": false, 81 | "type": "string", 82 | "value": "1" 83 | }, 84 | "backbone_z2_count": { 85 | "sensitive": false, 86 | "type": "string", 87 | "value": "0" 88 | }, 89 | "cf_admin_pass": { 90 | "sensitive": true, 91 | "type": "string", 92 | "value": "notarealpass" 93 | }, 94 | "cf_apps_subdomain": { 95 | "sensitive": false, 96 | "type": "string", 97 | "value": "apps" 98 | }, 99 | "cf_boshworkspace_version": { 100 | "sensitive": false, 101 | "type": "string", 102 | "value": "v1.2.0" 103 | }, 104 | "cf_domain": { 105 | "sensitive": false, 106 | "type": "string", 107 | "value": "XIP" 108 | }, 109 | "cf_release_version": { 110 | "sensitive": false, 111 | "type": "string", 112 | "value": "222" 113 | }, 114 | "cf_run_subdomain": { 115 | "sensitive": false, 116 | "type": "string", 117 | "value": "run" 118 | }, 119 | "cf_size": { 120 | "sensitive": false, 121 | "type": "string", 122 | "value": "tiny" 123 | }, 124 | "data_resource_pool": { 125 | "sensitive": false, 126 | "type": "string", 127 | "value": "large" 128 | }, 129 | "debug": { 130 | "sensitive": false, 131 | "type": "string", 132 | "value": "false" 133 | }, 134 | "health_resource_pool": { 135 | "sensitive": false, 136 | "type": "string", 137 | "value": "medium" 138 | }, 139 | "health_z1_count": { 140 | "sensitive": false, 141 | "type": "string", 142 | "value": "1" 143 | }, 144 | "health_z2_count": { 145 | "sensitive": false, 146 | "type": "string", 147 | "value": "0" 148 | }, 149 | "install_docker_services": { 150 | "sensitive": false, 151 | "type": "string", 152 | "value": "false" 153 | }, 154 | "install_logsearch": { 155 | "sensitive": false, 156 | "type": "string", 157 | "value": "false" 158 | }, 159 | "ipmask": { 160 | "sensitive": false, 161 | "type": "string", 162 | "value": "10.10" 163 | }, 164 | "private_cf_domains": { 165 | "sensitive": false, 166 | "type": "string", 167 | "value": "" 168 | }, 169 | "private_haproxy_resource_pool": { 170 | "sensitive": false, 171 | "type": "string", 172 | "value": "small" 173 | }, 174 | "public_haproxy_resource_pool": { 175 | "sensitive": false, 176 | "type": "string", 177 | "value": "small" 178 | }, 179 | "runner_resource_pool": { 180 | "sensitive": false, 181 | "type": "string", 182 | "value": "runner" 183 | }, 184 | "runner_z1_count": { 185 | "sensitive": false, 186 | "type": "string", 187 | "value": "1" 188 | }, 189 | "runner_z2_count": { 190 | "sensitive": false, 191 | "type": "string", 192 | "value": "0" 193 | }, 194 | "services_resource_pool": { 195 | "sensitive": false, 196 | "type": "string", 197 | "value": "medium" 198 | }, 199 | "services_z1_count": { 200 | "sensitive": false, 201 | "type": "string", 202 | "value": "1" 203 | }, 204 | "services_z2_count": { 205 | "sensitive": false, 206 | "type": "string", 207 | "value": "0" 208 | } 209 | }, 210 | "resources": {} 211 | }, 212 | { 213 | "path": [ 214 | "root", 215 | "cf-net" 216 | ], 217 | "outputs": { 218 | "aws_subnet_lb_availability_zone": { 219 | "sensitive": false, 220 | "type": "string", 221 | "value": "eu-west-1a" 222 | } 223 | }, 224 | "resources": {} 225 | }, 226 | { 227 | "path": [ 228 | "root", 229 | "vpc" 230 | ], 231 | "outputs": {}, 232 | "resources": {} 233 | } 234 | ] 235 | } 236 | 237 | http_version: 238 | recorded_at: Sun, 03 Jun 2018 14:24:43 GMT 239 | recorded_with: VCR 3.0.3 240 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/get_file_list_from_options.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://bucket-for-tf-configuration-tests.s3.eu-west-1.amazonaws.com/this-is-a-test.json 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | Authorization: 11 | - redacted 12 | response: 13 | status: 14 | code: 200 15 | message: OK 16 | headers: 17 | X-Amz-Id-2: 18 | - OMyPRxVzPslR9cczdqX54mpuSaANp6SvUrG9wSeI0VPbe5aZGbH9zzkz4F5vo+rLqmoQ0FlG3Iw= 19 | X-Amz-Request-Id: 20 | - 9E09DF35A7C228C2 21 | Date: 22 | - Sun, 03 Jun 2018 14:24:43 GMT 23 | Last-Modified: 24 | - Wed, 19 Oct 2016 09:48:57 GMT 25 | Etag: 26 | - '"ee63cdd60f81652cb274eaa70f38fb7b"' 27 | Accept-Ranges: 28 | - bytes 29 | Content-Type: 30 | - application/octet-stream 31 | Content-Length: 32 | - '8' 33 | Server: 34 | - AmazonS3 35 | body: 36 | encoding: UTF-8 37 | string: 'word up 38 | 39 | ' 40 | http_version: 41 | recorded_at: Sun, 03 Jun 2018 14:24:42 GMT 42 | recorded_with: VCR 3.0.3 43 | -------------------------------------------------------------------------------- /spec/fixtures/vcr_cassettes/get_state_from_bucket.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://bucket-for-tf-configuration-tests.s3.eu-west-1.amazonaws.com/this-is-a-test.json 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | Authorization: 11 | - redacted 12 | response: 13 | status: 14 | code: 200 15 | message: OK 16 | headers: 17 | X-Amz-Id-2: 18 | - ICBsP49GKYO3rPfnbMSE5t22LbV1fZWj6jHHdH1++5EDH93x74k4MhgnFKn16bqQMUYo7nINqFI= 19 | X-Amz-Request-Id: 20 | - F67B549049FD1BCD 21 | Date: 22 | - Sun, 03 Jun 2018 14:24:43 GMT 23 | Last-Modified: 24 | - Wed, 19 Oct 2016 09:48:57 GMT 25 | Etag: 26 | - '"ee63cdd60f81652cb274eaa70f38fb7b"' 27 | Accept-Ranges: 28 | - bytes 29 | Content-Type: 30 | - application/octet-stream 31 | Content-Length: 32 | - '8' 33 | Server: 34 | - AmazonS3 35 | body: 36 | encoding: UTF-8 37 | string: 'word up 38 | 39 | ' 40 | http_version: 41 | recorded_at: Sun, 03 Jun 2018 14:24:42 GMT 42 | recorded_with: VCR 3.0.3 43 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | require_relative '../lib/tfoutputs/configurator/state_reader' 3 | require_relative '../lib/tfoutputs/configurator/state_configurator' 4 | require_relative '../lib/tfoutputs/configurator/backends/s3_state_configuration' 5 | require_relative '../lib/tfoutputs/configurator/backends/file_state_configuration' 6 | -------------------------------------------------------------------------------- /spec/spec_helper_acceptance.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | require_relative '../lib/tfoutputs/configurator/backends/s3_state_configuration' 3 | require 'webmock/rspec' 4 | require 'vcr' 5 | require 'tfoutputs' 6 | WebMock.disable_net_connect! 7 | VCR.configure do |c| 8 | c.cassette_library_dir = 'spec/fixtures/vcr_cassettes' 9 | c.hook_into :webmock 10 | end 11 | -------------------------------------------------------------------------------- /spec/unit/resources/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "terraform_version": "0.7.0", 4 | "serial": 9, 5 | "lineage": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa", 6 | "modules": [ 7 | { 8 | "path": [ 9 | "root" 10 | ], 11 | "outputs": { 12 | "allowed_ips": { 13 | "sensitive": false, 14 | "type": "string", 15 | "value": "10.5.1.6/32" 16 | }, 17 | "api_resource_pool": { 18 | "sensitive": false, 19 | "type": "string", 20 | "value": "medium" 21 | }, 22 | "api_z1_count": { 23 | "sensitive": false, 24 | "type": "string", 25 | "value": "1" 26 | }, 27 | "api_z2_count": { 28 | "sensitive": false, 29 | "type": "string", 30 | "value": "0" 31 | }, 32 | "aws_region": { 33 | "sensitive": false, 34 | "type": "string", 35 | "value": "eu-west-1" 36 | }, 37 | "backbone_resource_pool": { 38 | "sensitive": false, 39 | "type": "string", 40 | "value": "large" 41 | }, 42 | "backbone_z1_count": { 43 | "sensitive": false, 44 | "type": "string", 45 | "value": "1" 46 | }, 47 | "backbone_z2_count": { 48 | "sensitive": false, 49 | "type": "string", 50 | "value": "0" 51 | }, 52 | "cf_admin_pass": { 53 | "sensitive": true, 54 | "type": "string", 55 | "value": "notarealpass" 56 | }, 57 | "cf_apps_subdomain": { 58 | "sensitive": false, 59 | "type": "string", 60 | "value": "apps" 61 | }, 62 | "cf_boshworkspace_version": { 63 | "sensitive": false, 64 | "type": "string", 65 | "value": "v1.2.0" 66 | }, 67 | "cf_domain": { 68 | "sensitive": false, 69 | "type": "string", 70 | "value": "XIP" 71 | }, 72 | "cf_release_version": { 73 | "sensitive": false, 74 | "type": "string", 75 | "value": "222" 76 | }, 77 | "cf_run_subdomain": { 78 | "sensitive": false, 79 | "type": "string", 80 | "value": "run" 81 | }, 82 | "cf_size": { 83 | "sensitive": false, 84 | "type": "string", 85 | "value": "tiny" 86 | }, 87 | "data_resource_pool": { 88 | "sensitive": false, 89 | "type": "string", 90 | "value": "large" 91 | }, 92 | "debug": { 93 | "sensitive": false, 94 | "type": "string", 95 | "value": "false" 96 | }, 97 | "health_resource_pool": { 98 | "sensitive": false, 99 | "type": "string", 100 | "value": "medium" 101 | }, 102 | "health_z1_count": { 103 | "sensitive": false, 104 | "type": "string", 105 | "value": "1" 106 | }, 107 | "health_z2_count": { 108 | "sensitive": false, 109 | "type": "string", 110 | "value": "0" 111 | }, 112 | "install_docker_services": { 113 | "sensitive": false, 114 | "type": "string", 115 | "value": "false" 116 | }, 117 | "install_logsearch": { 118 | "sensitive": false, 119 | "type": "string", 120 | "value": "false" 121 | }, 122 | "ipmask": { 123 | "sensitive": false, 124 | "type": "string", 125 | "value": "10.10" 126 | }, 127 | "private_cf_domains": { 128 | "sensitive": false, 129 | "type": "string", 130 | "value": "" 131 | }, 132 | "private_haproxy_resource_pool": { 133 | "sensitive": false, 134 | "type": "string", 135 | "value": "small" 136 | }, 137 | "public_haproxy_resource_pool": { 138 | "sensitive": false, 139 | "type": "string", 140 | "value": "small" 141 | }, 142 | "runner_resource_pool": { 143 | "sensitive": false, 144 | "type": "string", 145 | "value": "runner" 146 | }, 147 | "runner_z1_count": { 148 | "sensitive": false, 149 | "type": "string", 150 | "value": "1" 151 | }, 152 | "runner_z2_count": { 153 | "sensitive": false, 154 | "type": "string", 155 | "value": "0" 156 | }, 157 | "services_resource_pool": { 158 | "sensitive": false, 159 | "type": "string", 160 | "value": "medium" 161 | }, 162 | "services_z1_count": { 163 | "sensitive": false, 164 | "type": "string", 165 | "value": "1" 166 | }, 167 | "services_z2_count": { 168 | "sensitive": false, 169 | "type": "string", 170 | "value": "0" 171 | } 172 | }, 173 | "resources": {} 174 | }, 175 | { 176 | "path": [ 177 | "root", 178 | "cf-net" 179 | ], 180 | "outputs": { 181 | "aws_subnet_lb_availability_zone": { 182 | "sensitive": false, 183 | "type": "string", 184 | "value": "eu-west-1a" 185 | } 186 | }, 187 | "resources": {} 188 | }, 189 | { 190 | "path": [ 191 | "root", 192 | "vpc" 193 | ], 194 | "outputs": {}, 195 | "resources": {} 196 | } 197 | ] 198 | } 199 | 200 | -------------------------------------------------------------------------------- /spec/unit/state_reader_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'state reader' do 4 | before(:each) do 5 | cwd = File.expand_path(File.dirname(__FILE__)) 6 | @tf_state = "#{cwd}/resources/terraform.tfstate" 7 | end 8 | 9 | it 'should get outputs' do 10 | sr = TfOutputs::Configurator::StateReader.new(@tf_state => false) 11 | expected = { 'allowed_ips' => { 'sensitive' => false, 'type' => 'string', 'value' => '10.5.1.6/32' } } 12 | expect(sr.outputs).to include(expected) 13 | end 14 | 15 | it 'respond_to should work' do 16 | sr = TfOutputs::Configurator::StateReader.new(@tf_state => false) 17 | expect(sr.send(:respond_to?, :allowed_ips)).to eq(true) 18 | end 19 | it 'method missing should work' do 20 | sr = TfOutputs::Configurator::StateReader.new(@tf_state => false) 21 | expect(sr.allowed_ips).to eq('10.5.1.6/32') 22 | end 23 | it "method missing should fail when a variable from state file isn't returned" do 24 | sr = TfOutputs::Configurator::StateReader.new(@tf_state => false) 25 | expect { sr.bastion_ipasdad }.to raise_error(NoMethodError) 26 | end 27 | 28 | it 'should return sensitive for a sensitive value' do 29 | sr = TfOutputs::Configurator::StateReader.new(@tf_state => false) 30 | expect(sr.cf_admin_pass).to eq('sensitive') 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /tfoutputs.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'tfoutputs/configurator/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = 'tfoutputs' 8 | spec.version = TfOutputs::Configurator::VERSION 9 | spec.authors = ['James Edwards'] 10 | spec.email = ['admin@jaetech.org'] 11 | 12 | spec.summary = 'Gem for grabbing variables from terraform' 13 | spec.description = 'Sometimes we want to use the outputs of terraform in our ruby code for generating dashboard etc.. This gem enables this' 14 | spec.homepage = 'https://github.com/jae2/ruby-tfoutputs' 15 | spec.license = 'MIT' 16 | 17 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|fixtures)/}) } 18 | spec.require_paths = ['lib'] 19 | 20 | spec.add_development_dependency 'bundler' 21 | spec.add_development_dependency 'rake', '~> 10.0' 22 | spec.add_development_dependency 'rubocop' 23 | spec.add_runtime_dependency 'aws-sdk-s3', '~> 1' 24 | spec.add_development_dependency 'rspec', '~> 3.5' 25 | spec.add_development_dependency 'vcr', '~>3.0' 26 | spec.add_development_dependency 'webmock', '~> 2.1' 27 | end 28 | --------------------------------------------------------------------------------