nhurel / terraspec Goto Github PK
View Code? Open in Web Editor NEWTerraform unit test framework
License: Mozilla Public License 2.0
Terraform unit test framework
License: Mozilla Public License 2.0
Hi!
It seems we do not have support for module variables:
Unassigned variable : The input variable "account_id" has not been assigned a value. This is a bug in Terraform; please report it in a GitHub issue.
Is there any plan to add this feature @nhurel?
Hi,
if I execute
go get github.com/nhurel/[email protected]
the call fails with:
go: github.com/nhurel/terraspec 0.6.2 => v0.0.0-20201014212445-68dbde0cfbf6
go: finding module for package k8s.io/client-go/kubernetes/typed/coordination/v1
go: finding module for package github.com/peterbourgon/diskv
go: finding module for package github.com/gregjones/httpcache
go: finding module for package github.com/gregjones/httpcache/diskcache
go: finding module for package k8s.io/api/admissionregistration/v1alpha1
go: found k8s.io/client-go/kubernetes/typed/coordination/v1 in k8s.io/client-go v11.0.0+incompatible
go: found github.com/gregjones/httpcache in github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
go: found github.com/gregjones/httpcache/diskcache in github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
go: found github.com/peterbourgon/diskv in github.com/peterbourgon/diskv v2.0.1+incompatible
# k8s.io/client-go/rest
go\pkg\mod\k8s.io\[email protected]+incompatible\rest\request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
have (*versioned.Decoder)
want (watch.Decoder, watch.Reporter)
PS C:\Users\jogruen> go get github.com/nhurel/[email protected]
go: github.com/nhurel/terraspec 0.6.2 => v0.0.0-20201014212445-68dbde0cfbf6
go: finding module for package k8s.io/client-go/kubernetes/typed/coordination/v1
go: finding module for package k8s.io/api/admissionregistration/v1alpha1
go: finding module for package github.com/gregjones/httpcache
go: finding module for package github.com/peterbourgon/diskv
go: finding module for package github.com/gregjones/httpcache/diskcache
go: found k8s.io/client-go/kubernetes/typed/coordination/v1 in k8s.io/client-go v11.0.0+incompatible
go: found github.com/gregjones/httpcache in github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
go: found github.com/gregjones/httpcache/diskcache in github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
go: found github.com/peterbourgon/diskv in github.com/peterbourgon/diskv v2.0.1+incompatible
# k8s.io/client-go/rest
go\pkg\mod\k8s.io\[email protected]+incompatible\rest\request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
have (*versioned.Decoder)
want (watch.Decoder, watch.Reporter)
This seems to be an issue with transitive dependencies. It looks like terraform 0.13 depends on client-go
for some reason and does so by referencing v10.0.0+incompatible
which is pretty old and not a go module. Seems like they have changed from major version 11 back to version 0 at some point and that is causing some trouble. The k8s api module does not have a major version yet and it seems to mix the very old client-go
version with a new k8s api version.
I am still curious why terraform requires a reference to client-go
because they should not be dependent on kubernetes.
Right now terraspec is using v0.13.5. We tried to update it to v0.14.6 (or any other 0.14.x versions) and we gave up because I couldn't even call go get ./...
because go is crying about checksum mismatch. Later I discovered the same happens on the upstream hashicorp/terraform repository as well.
I don't know what can be the solution or how to approach it, I'm opening this issue to take a public note about it (if others have the same problem). We may try to do it later, but now we are just pinning all terraform to v0.13.5.
terraform workpace is used to create multiple of the same tf stack. The variable terraform.workspace is is used to create unique names for resources to not collide. When terraspecing the tf code it fails with a null pointer exception. My guess is that this is just piping that has not been added yet.
main.tfspec:
assert "aws_ssm_parameter" "eks_kubernetes_image_ssm" {
name = "/my/ssm/parameter"
type = "String"
value = "null"
}
This main.tf works fine:
terraform {
required_version = ">= 0.13.0, < 0.14.0"
required_providers {
aws = "~> 2.0"
}
}
resource "aws_ssm_parameter" "eks_kubernetes_image_ssm" {
name = "/my/ssm/parameter"
type = "String"
value = "null"
}
This main.tf fails:
terraform {
required_version = ">= 0.13.0, < 0.14.0"
required_providers {
aws = "~> 3.0"
}
}
resource "aws_ssm_parameter" "eks_kubernetes_image_ssm" {
name = "/my/ssm/parameter"
type = "String"
value = "null"
}
Failure:
rpc error: code = Unavailable desc = transport is closing :
Modules have variables and outputs which theoretically can be mocked/stubbed out. This feature would promote units when working with modules because every resource in the module can be tested in explicit spec tests in the module and not at the level of the terraform that is using the module. Not sure there is support yet to do this but I couldn't find anything.
something like
assert_module "module_name" {
some_variable_name = "some_variable_value"
return {
some_output_name = "some_output_value"
}
}
Right the master uses github.com/hashicorp/terraform v0.14.9
. As Terraform 1.0 was announced. Everything should work from v0.15, but Terraspec uses v0.14 which can be an issue (should not).
Starting with Terraform 0.15 and continuing through the lifecycle of 1.x, you can now upgrade to a new Terraform version and your workflows will continue to be operational, just as they were in those prior versions. There is no requirement for upgrade tools, refactoring, or other changes in order to use Terraform 1.x.
At the same time "Terraform Plugin SDK v1 End of Life".
A separate branch for that would be good/enough to start experimenting with it.
We will start updating our tooling in a few weeks, so we will try to update it and come back if something blows up. If everything is working, we will come back with a PR if it's not resolved yet.
Hello,
I want to check that a resource that is not covered in main.tf will be created., but Terraspec is crashing with SIGSEGV error
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x1ae9aa7]goroutine 51 [running]:
github.com/nhurel/terraspec/lib.laxSchema(0x0, 0xc001770970)
/root/source/lib/spec.go:551 +0x37
github.com/nhurel/terraspec/lib.decodeBody(0x25261c0, 0xc0029ef340, 0xc001770970, 0xd, 0xc000229340, 0xc003e6b340, 0x0, 0x0, 0x0, 0x0, ...)
/root/source/lib/spec.go:489 +0x13e
github.com/nhurel/terraspec/lib.ParseSpec(0xc000158000, 0x1292, 0x1492, 0xc0004ef800, 0x1b, 0xc000229340, 0x0, 0x0, 0x0, 0x0)
/root/source/lib/spec.go:426 +0x470
github.com/nhurel/terraspec/lib.ReadSpec(0xc0004ef800, 0x1b, 0xc000229340, 0xc00052fd00, 0x1, 0x1, 0x0)
/root/source/lib/spec.go:361 +0x1cc
main.PrepareTestSuite(0x202de65, 0x1, 0xc0002a4930, 0xc0004c1d80, 0x0, 0x0, 0x0, 0x0, 0x0)
/root/source/main.go:209 +0x40b
main.runTestCase(0xc0002a4930, 0xc0004c1d80, 0x0, 0xc0005ba300)
/root/source/main.go:137 +0x6a
main.execTerraspec.func1(0xc0004c1d80, 0x0, 0xc0005ba300, 0xc0004cb170, 0xc0002a4930)
/root/source/main.go:95 +0x48
created by main.execTerraspec
/root/source/main.go:94 +0x1dd
There is example of code spec/default/default.tfspec
assert "random_string" "some_password" {
length = 16
lower = true
min_lower = 0
min_numeric = 0
min_special = 0
min_upper = 0
number = true
special = false
upper = true
}
Terraspec Version : 0.7.19
Terraform Version : 0.13.5
There is an issue when trying to explicitly mocking two different instances of the same module.
in the module "./modules/test"
data "aws_region" "this_module" {}
using module
provider "aws" {
alias = "us-east-1"
region = "us-east-1"
version = "2.68.0"
}
provider "aws" {
alias = "us-west-2"
region = "us-west-2"
version = "2.68.0"
}
module "us-east-1" {
providers = {
aws = aws.us-east-1
}
source = "./modules/test"
}
module "us-west-2" {
providers = {
aws = aws.us-west-2
}
source = "./modules/test"
}
Attempting to do it like assert
mock "module.us-east-1.aws_region" "this_module" {
return {
name = "us-east-1"
}
}
mock "module.us-west-2.aws_region" "this_module" {
return {
name = "us-west-2"
}
}
I get the error: Cannot find schema : unknown provider
I can try to do it this way
mock "aws_region" "module.CAN_BE_ANYTHING.this_module" {
return {
name = "CAN ONLY BE ONE VALUE"
}
}
this works however it sets it for every single module
When running 0.2.0 I hit
root@fc047254b97d:/terraspec# ../terraspec-linux-x64 --spec=examples/aws/spec/default
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x135ecc7]
goroutine 7 [running]:
github.com/nhurel/terraspec/lib.laxSchema(0x0, 0xc0004c68d0)
/go/src/github.com/nhurel/terraspec/lib/spec.go:343 +0x37
github.com/nhurel/terraspec/lib.decodeBody(0xc00007f060, 0xc000040a20, 0x20, 0xc00006b700, 0xc00008b6d0, 0x0, 0x0, 0x0, 0xc00007ee80, 0x0, ...)
/go/src/github.com/nhurel/terraspec/lib/spec.go:296 +0x134
github.com/nhurel/terraspec/lib.ParseSpec(0xc00015c800, 0x58b, 0x78b, 0xc0000b4750, 0x28, 0xc00006b700, 0x0, 0x0, 0x1b2ea80, 0x0)
/go/src/github.com/nhurel/terraspec/lib/spec.go:259 +0x231
github.com/nhurel/terraspec/lib.ReadSpec(0xc0000b4750, 0x28, 0xc00006b700, 0xc0000cbe00, 0x1, 0x1, 0x0)
/go/src/github.com/nhurel/terraspec/lib/spec.go:219 +0x1a4
main.PrepareTestSuite(0x17677c5, 0x1, 0xc00021ddd0, 0x0, 0x0, 0x0, 0x0, 0x0)
/go/src/github.com/nhurel/terraspec/main.go:152 +0x2ca
main.runTestCase(0xc00021ddd0, 0xc0000d2540)
/go/src/github.com/nhurel/terraspec/main.go:92 +0x5d
main.main.func1(0xc0000d2540, 0xc000042a40, 0xc00021ddd0)
/go/src/github.com/nhurel/terraspec/main.go:64 +0x35
created by main.main
/go/src/github.com/nhurel/terraspec/main.go:63 +0x1d5
when running in 0.1.6 it seemed to work fine however there are a lot of features not in 0.1.6.
root@fc047254b97d:/terraspec/examples/aws# /terraspec/terraspec-linux-x64 --spec=spec/default/
๐ท default
โ module.ec2-instance.aws_instance.this[0].associate_public_ip_address = false
โ module.ec2-instance.aws_instance.this[0].credit_specification[0].cpu_credits = standard
โ module.ec2-instance.aws_instance.this[0].disable_api_termination = false
โ module.ec2-instance.aws_instance.this[0].ebs_optimized = false
โ module.ec2-instance.aws_instance.this[0].get_password_data = false
โ module.ec2-instance.aws_instance.this[0].instance_type = t2.small
โ module.ec2-instance.aws_instance.this[0].monitoring = false
โ module.ec2-instance.aws_instance.this[0].source_dest_check = true
โ module.ec2-instance.aws_instance.this[0].subnet_id = mocked_subnet_id
โ module.ec2-instance.aws_instance.this[0].tags.Name = my-instance
โ module.ec2-instance.aws_instance.this[0].tenancy = default
โ module.ec2-instance.aws_instance.this[0].volume_tags.Name = my-instance
main.tf
resource "null_resource" "resource" { }
data "null_data_source" "data" {
inputs = {
my_test_value = null_resource.resource.id
}
}
main.tfspec
expect "null_resource" "resource" {
return {
id = "test_id"
}
}
mock "null_data_source" "data" {
inputs = {
my_test_value = "test_id"
}
}
error when run from terminal
$ terraspec --spec="spec/"
๐ท spec
โ null_data_source.data : No data resource matched :
{
inputs = {
my_test_value = "test_id"
}
}
Uncatched data source calls are :
๐ 1 suites run in 3.469326573s error : 1 success : 0
Hello,
I'm currently using the tool for local development (thanks).
Now I'm integrating the testing into my CI/CD workflow. For that, I built an image that contains terraspec and terraform.
Are you interested in adding the corresponding Dockerfile to this repository?
Hello,
I am trying to run terraspec (assuming terraform version v0.12.21) and seems like it is ignoring *.tfvars files with variables defined:
/root/terraspec-linux-x64 --spec /mnt/ --claim-version=v0.12.21
๐ท mnt
Unassigned variable : The input variable "environment" has not been assigned a value. This is a bug in Terraform; please report it in a GitHub issue.
๐ 1 suites run in 21.4598379s error : 1 success : 0
Terraform version 0.13.5 substitued with provided one 0.12.21
For a project with multiple modules in the same project (e.g., modules/foo
, modules/bar
, modules/baz/qux
), is there a way to have terraspec find all the specs and recurse over them, whether that's laid out like modules/foo/spec
or test/spec/modules/foo
? Will it take a glob pattern like
% terraspec test/spec/**/**
or similar?
Also, in the examples, it seems as if you can have multiple test cases using the same .tf
files, but different tfvars. But what if you want to instantiate the module in a completely different way -- is there a suggested structure for handling that?
runtime: netpoll: break fd ready for -2
fatal error: runtime: netpoll: break fd ready for something unexpected
runtime stack:
runtime.throw(0x23ac12c, 0x39)
/usr/local/go/src/runtime/panic.go:1116 +0x72
runtime.netpoll(0x205bc9, 0x622a3021a201)
/usr/local/go/src/runtime/netpoll_kqueue.go:140 +0x30a
runtime.findrunnable(0xc00004e800, 0x0)
/usr/local/go/src/runtime/proc.go:2329 +0x72b
runtime.schedule()
/usr/local/go/src/runtime/proc.go:2526 +0x2fc
runtime.park_m(0xc000000c00)
/usr/local/go/src/runtime/proc.go:2696 +0x9d
runtime.mcall(0x80000)
/usr/local/go/src/runtime/asm_amd64.s:318 +0x5b
goroutine 1 [runnable, locked to thread]:
github.com/ChrisTrenkamp/goxpath/parser.init()
/go/pkg/mod/github.com/!chris!trenkamp/[email protected]/parser/ast.go:19
goroutine 18 [select]:
go.opencensus.io/stats/view.(*worker).start(0xc00008d900)
/go/pkg/mod/[email protected]/stats/view/worker.go:154 +0x100
created by go.opencensus.io/stats/view.init.0
/go/pkg/mod/[email protected]/stats/view/worker.go:32 +0x57
Hi --
Thanks for building this tool. I've had my eye on it for a while, because this is the exact thing I've been looking for for ages, and finally got around to trying to setup some test cases.
I built off the tf0.14 branch (per #14), and tried to create a simple test case, however, I'm wondering if the changes in the way the registry works with 0.14 is causing an issue?
in main.tf
:
module "test-cluster" {
source = "../../../modules/gke_cluster"
name = "testy"
location = "us-central1"
// some stuff skipped here [...]
}
terraform {
required_version = ">= 0.14"
required_providers {
google = {
source = "hashicorp/google"
}
google-beta = {
source = "hashicorp/google-beta"
}
}
}
% tree
.
โโโ modules_gke_cluster_simple
โโโ main.tf
โโโ spec
โโโ default
โโโ default.tfspec
## from within modules_gke_cluster_simple
% tf init --backend=false
Initializing modules...
- test-cluster in ../../../modules/gke_cluster
Initializing provider plugins...
- Finding latest version of hashicorp/google-beta...
- Finding latest version of hashicorp/google...
- Using hashicorp/google v3.58.0 from the shared cache directory
- Using hashicorp/google-beta v3.58.0 from the shared cache directory
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
% terraspec
๐ท default
Failed to instantiate provider "registry.terraform.io/hashicorp/google" to obtain schema: unknown provider "registry.terraform.io/hashicorp/google" :
Failed to instantiate provider "registry.terraform.io/hashicorp/google-beta" to obtain schema: unknown provider "registry.terraform.io/hashicorp/google-beta" :
๐ 1 suites run in 3.848539ms error : 1 success : 0
After playing around a bit somethings I have found that are missing. such as values returned from the provider once resource is created should probably be able to be mocked. Ex:
resource "aws_s3_bucket" "b" {
bucket = "my-tf-test-bucket"
}
output "private_ip" {
value = aws_s3_bucket.b.id
}
spec could be something like
assert "aws_s3_bucket" "c" {
bucket = "my-tf-test-bucket"
return {
id = "arn:aws:s3::0000000000:my-tf-test-bucket"
}
}
assert "output" "private_ip" {
value = "arn:aws:s3::0000000000:my-tf-test-bucket"
}
Terraform supports finding providers in the terraform.d/plugins
folder.
This folder is located in:
%APPDATA%\terraform.d\plugins
~/terraform.d/plugins
Terraspec only seems to load plugins from the folder <projectDir>/.terraform/plugins/<os>_<arch>
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.