Skip to content
This repository has been archived by the owner on Jan 19, 2023. It is now read-only.
/ rspec-terraform Public archive

RSpec Unit testing for Terraform plans

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.txt
Notifications You must be signed in to change notification settings

highwingio/rspec-terraform

Rspec::Terraform

This project provides RSpec helpers for unit testing terraform plan output. It is born out of the pain of trying to create reusable terraform modules and having them break or behave in unexpected ways when the plans have not been reviewed for all possible use cases. rspec-terraform gives you a way to write expectations for your terraform plans and automate validation prior to attempting to go live.

Installation

Install the gem and add to a project Gemfile by executing:

$ bundle add rspec-terraform

If bundler is not being used to manage dependencies, install the gem by executing:

$ gem install rspec-terraform

Usage

Let's say that we've created a nonsensical module that creates an S3 bucket and hides all the details behind some absurd params:

# main.tf
variable "is_this_a_test" {
  type = string
  default = "please-no"
}

resource "aws_s3_bucket" "what" {
  bucket = var.is_this_a_test

  tags = {
    Name        = var.is_this_a_test
    Environment = "My Brain Hurts"
  }
}

Then, we might create some example configuration files for documentation and testing's sake which utilizes your custom module:

# examples/my-module/main.tf

module "my-module" {
  source = "../my-custom-module"
  
  is_this_a_test = "most-definitely"
}

module "my-other-module-with-defaults" {
  source = "../my-custom-module"
}

Now, instead of running a plan manually, with rspec-terraform, we can add require 'rspec/terraform to our spec_helper.rb file and then write specs:

require 'spec_helper'

RSpec.describe "my-terraform-module" do
  # If you do not want to run the plan for every `it` block, use this approach. Otherwise you can use `subject` or 
  # `it(:plan) { terraform_plan('my-module') }`

  before :all do
    @plan = terraform_plan('my-module')
  end

  it "returns a plan successfully" do
    expect(@plan).to be_a(RubyTerraform::Models::Plan)
  end

  context "resources" do
    let(:buckets) { @plan.resource_changes_matching(type: "aws_s3_bucket") }
    let(:mod_bucket) { buckets.first.change.after }
    let(:default_bucket) { buckets.last.change.after }

    it "creates the required buckets" do
      expect(buckets.count).to eq(2)
      expect(buckets).to all(be_create)
    end

    it "uses the parameters passed" do
      expect(bucket[:id]).to eq('most-definitely')
    end

    it "uses defaults" do
      expect(bucket[:id]).to eq('please-no')
    end
  end
end

You can then run rspec as you normally would!

⚠️ Keep in mind, that if you want to use third-party providers (like AWS), you will need to have credentials provided in the normal way.

To understand the data structure returned by the plan, please refer to the RubyTerraform project's models. However, for the most part, you can assume traversal in the change objects (as used above) to match the terraform output generated by plan show <plan> -json (documented here).

I would heartily recommend traversing the code for RubyTerraform's models as there are a number of helper methods that make testing and scoping resources less painful.

Configuration options

RSpec.configure do |config|
  # set the path to your terraform binary
  config.terraform_binary = 'path/to/terraform/executable' # default: "/Users/`whoami`/.asdf/shims/terraform"
  
  # disable plan output during the test run. Useful to enabled during initial testing, but can get pretty noisy
  config.silence_terraform_output = true  # default: false
  
  # base directory for terraform examples, relative to where rspec is executed 
  config.terraform_examples_dir = "my/terraform/examples" # default: 'examples'
end

Development

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.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rspec-terraform.

Acknowledgement

Many thanks to the folks behind RubyTerraform. The project code is a joy to read and it is surprising to find so many unassuming gems like the entirely unexposed [models code](https://github. com/infrablocks/ruby_terraform/tree/main/lib/ruby_terraform/models)!

License

The gem is available as open source under the terms of the MIT License.

About

RSpec Unit testing for Terraform plans

Resources

License

MIT, MIT licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.txt

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published