https://github.com/infrablocks/rspec-terraform
RSpec support for testing Terraform configurations.
https://github.com/infrablocks/rspec-terraform
automation infrastructure rspec ruby ruby-gem ruby-rspec rubygem terraform
Last synced: 11 months ago
JSON representation
RSpec support for testing Terraform configurations.
- Host: GitHub
- URL: https://github.com/infrablocks/rspec-terraform
- Owner: infrablocks
- License: mit
- Created: 2022-07-02T22:17:08.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-03-13T11:41:43.000Z (12 months ago)
- Last Synced: 2025-03-24T12:21:47.282Z (11 months ago)
- Topics: automation, infrastructure, rspec, ruby, ruby-gem, ruby-rspec, rubygem, terraform
- Language: Ruby
- Homepage:
- Size: 373 KB
- Stars: 6
- Watchers: 7
- Forks: 1
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# RSpec::Terraform
An RSpec extension for verifying Terraform configurations, with support for:
* unit testing;
* integration testing;
* end-to-end testing; and
* change auditing.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'rspec-terraform'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install rspec-terraform
## Usage
To use RSpec::Terraform, require it in your `spec_helper.rb` file:
```ruby
require 'rspec/terraform'
```
When required, RSpec::Terraform automatically configures itself against
RSpec by:
* adding helper methods to interact with Terraform;
* adding matchers to verify Terraform plans; and
* adding settings to control RSpec::Terraform's behaviour.
The sections below provide further details on each of these additions.
### Helper methods
RSpec::Terraform adds helper methods to the RSpec DSL for planning, applying,
and destroying Terraform configurations, as well as accessing variables to and
outputs from Terraform configurations.
Each helper method takes a hash of parameters used to identify the configuration
against which to act and to provide as options to the Terraform command being
executed. Additionally, RSpec::Terraform includes a flexible approach to
resolving these parameters allowing them to be sourced from a variety of
locations. See the [Configuration Providers](#configuration-providers) section
for more details.
When executing helper methods, RSpec::Terraform provides two execution modes,
`:in_place` and `:isolated`. By default, RSpec::Terraform works against a
Terraform configuration _in place_, i.e., it executes commands against the
Terraform configuration directly, in the location specified. RSpec::Terraform
can also operate in an _isolated_ manner, wherein it initialises the
configuration into an isolated directory before executing commands. See the
[Execution Mode](#execution-mode) section for more details.
#### `plan`
The `plan` helper produces a Terraform plan for a configuration, reads it
into a Ruby representation and returns it.
`plan` requires a `:configuration_directory` parameter, representing the path
to the configuration to plan and is typically invoked in a `before(:context)`
hook, with the resulting plan stored for use in expectations:
```ruby
before(:context) do
@plan = plan(
configuration_directory: 'path/to/configuration/directory'
)
end
```
If the configuration has input variables, a `:vars` parameter can be provided
as a hash:
```ruby
before(:context) do
@plan = plan(
configuration_directory: 'path/to/configuration/directory',
vars: {
region: 'uk',
zones: ['uk-a', 'uk-b'],
tags: {
name: 'important-thing',
role: 'persistence'
}
}
)
end
```
or within a block:
```ruby
before(:context) do
@plan = plan(
configuration_directory: 'path/to/configuration/directory'
) do |vars|
vars.region = 'uk'
vars.zones = ['uk-a', 'uk-b']
vars.tags = {
name: 'important-thing',
role: 'persistence'
}
end
end
```
`plan` accepts an optional `:state_file` parameter with the path to where the
current state file for the configuration is located, useful when checking the
incremental change that applying the configuration would have after a previous
apply.
Internally, `plan`:
* calls `terraform init` to initialise the configuration directory;
* calls `terraform plan` to produce a plan file;
* calls `terraform show` to read the contents of the plan file into a Ruby
representation; and
* deletes the plan file.
Any additional parameters passed to `plan` are passed on to the underlying
Terraform invocations.
#### `apply`
#### `destroy`
#### `output`
#### `var`
### Plan Matchers
### Settings
#### Binary Location
#### Logging and Standard Streams
#### Execution Mode
The benefit of isolated execution is that nothing is carried over between test
runs and providers and modules are fetched into a clean configuration directory
every time. The downside is additional test run time.
#### Configuration Providers
### Frequently Asked Questions
## Development
To install dependencies and run the build, run the pre-commit build:
```shell
./go
```
This runs all unit tests and other checks including coverage and code linting /
formatting.
To run only the unit tests, including coverage:
```shell
./go test:unit
```
To attempt to fix any code linting / formatting issues:
```shell
./go library:fix
```
To check for code linting / formatting issues without fixing:
```shell
./go library:check
```
You can also run `bin/console` for an interactive prompt that will allow you to
experiment.
### Managing CircleCI keys
To encrypt a GPG key for use by CircleCI:
```bash
openssl aes-256-cbc \
-e \
-md sha1 \
-in ./config/secrets/ci/gpg.private \
-out ./.circleci/gpg.private.enc \
-k ""
```
To check decryption is working correctly:
```bash
openssl aes-256-cbc \
-d \
-md sha1 \
-in ./.circleci/gpg.private.enc \
-k ""
```
## Contributing
Bug reports and pull requests are welcome on GitHub at
https://github.com/infrablocks/rspec-terraform. 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.
## License
The gem is available as open source under the terms of the
[MIT License](http://opensource.org/licenses/MIT).