Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing Terragrunt? #122

Closed
kamsz opened this issue Jun 26, 2018 · 21 comments
Closed

Testing Terragrunt? #122

kamsz opened this issue Jun 26, 2018 · 21 comments
Labels
enhancement New feature or request

Comments

@kamsz
Copy link
Contributor

kamsz commented Jun 26, 2018

Is it possible to swap executable that is used from terraform to terragrunt?

@brikis98 brikis98 added enhancement New feature or request help wanted labels Jun 27, 2018
@brikis98
Copy link
Member

Not currently, but that's a great idea. A TerraformBinary field, which if empty defaults to terraform, would be a great addition to terraform.Options.

@kamsz
Copy link
Contributor Author

kamsz commented Jun 27, 2018

@brikis98 I'd stick with a separate module to include additional functionalities of Terragrunt like apply-all.

@brikis98
Copy link
Member

I think it would be cleaner to avoid duplicating all those code paths. To handle apply-all, we could expose a RunTerraformCommand(command string, args[]string, options *terraform.Options) method.

@kamsz
Copy link
Contributor Author

kamsz commented Jun 27, 2018

I'll try to work on this then.

@so87
Copy link

so87 commented Apr 25, 2019

I'm confused here: doesn't gruntwork exclusively use terragrunt to work on infrastructure? And shouldn't all "dev" "staging" and "production" folders have terratests written for them (because that is what you seem to suggest in both of your books). So how does gruntwork actually test terragrunt - do you just write terratests for modules, and use another tool to do smoke tests on terragrunt deployments? @brikis98

@brikis98
Copy link
Member

I'm confused here: doesn't gruntwork exclusively use terragrunt to work on infrastructure?

Not exclusively. All of the modules in our IaC Library, where we do the majority of our testing, are written in pure Terraform and do NOT require Terragrunt at all. Also, many of the modules are written in Go, Python, Bash, etc too, as the IaC Library is designed to solve problems across the entire infrastructure, and not just those problems that can be solved by Terraform.

So how does gruntwork actually test terragrunt

Terragrunt itself is tested in this repo. See the _test.go files.

do smoke tests on terragrunt deployments

Correct

@so87
Copy link

so87 commented Apr 25, 2019

@brikis98
Thank you for the fast response and time, you seem like an extremely busy person.
After further analyzing the terragrunt and terratest repos let me see if you think how I'm going to test my future configurations make sense. I tried looking for people using writing go tests for a terragrunt project layout, but couldn't find any - so maybe tons of people are using terragrunt but not actually writing any tests for their infrastructure?.

I want to take a docker image I have and get it running in ec2. So first I

  1. break out the necessary infrastructure pieces into a modules repository
  2. write failing tests for that terraform code using terratest. Keep working until tests pass
  3. reference that modules repository in my project repository where it has the following structure(using terragrunt). My _test.go files aren't terratest, they are just simple go tests that curl a url(I haven't written these yet but that was what I was thinking)
    project
  • dev
    • terraform.tfvars
  • staging
  • prod
    terraform.tfvars
    account.tfvars
  • tests
    • dev_test.go
    • staging_test.go
    • prod_test.go
  1. once I'm able to get all of this working for a simple ec2 "hello world" type image, I can now create a new folder for turning my existing Dockerfile into a container.json file that will be used by packer to build a docker image and turn it into an ami.
  2. write terratests for the container.json I made. This way any changes to this container infrastructure gets tested.
  3. write normal or python unit tests for the code that goes inside this container
  4. my ci/cd should run all terratest for the base infrastructure(aws,gcp), terratest to ensure image gets created(ami, docker image), normal unit testing for my app inside container, and go "smoke tests" to make sure that everything seems to be running after each deployment

Give me as much criticism as you feel like, I'm trying to learn the right way of doing things from you. I've been looking at your code, and half way done reading your book "hello startup". I really appreciate your work and writing.

@so87
Copy link

so87 commented Apr 30, 2019

@brikis98 does that seem right or is that overkill?

@brikis98
Copy link
Member

brikis98 commented May 1, 2019

Sorry, been buried, will take a look when I get a chance

@k3kh
Copy link

k3kh commented Feb 12, 2020

@so87 Have you ever resolved unit testing (terratest) and terragrunt items mentioned above? Interested in any approach. Working through some of the same items you mentioned above.

@yorinasub17
Copy link
Contributor

This is OT to the terragrunt testing workflow, but circling back on the OP, we've released a few functions since the issue was opened that help with testing Terragrunt:

@kihahu
Copy link

kihahu commented Mar 17, 2020

I recently used the option TerraformBinary and the apply-all and plan-all functions to write tests for terraform modules which are usually used using terragrunt. I happened on them by chance while looking at some test implementations.
I think some examples to illustrate the use of the option and functions would be helpful.

@brikis98
Copy link
Member

brikis98 commented Apr 1, 2020

As mentioned in this comment, you can now test Terragrunt.

@brikis98 brikis98 closed this as completed Apr 1, 2020
@pandu-bhojaraj-mf
Copy link

@kihahu @yorinasub17 @so87 @brikis98

Can any one of you share me piece of code which is written to invoke terragrunt(HCL) files from terratest(GO) script ?

I am getting "github.com/gruntwork-io/terratest/modules/terraform.(*TgInvalidBinary).Error" error for below code

image

Tryin hard to get some example code which helps me to invoke terragrunt files from terratest , please help

@yorinasub17
Copy link
Contributor

Try setting the TerraformBinary attribute on the Options struct to the path to terragrunt binary, and that should do the trick.

@avishnyakov
Copy link

avishnyakov commented Feb 22, 2021

Exploring options to swap Terraform with Terragrunt via options.TerraformDir at the moment.

This is extremely useful while testing Terraform modules on different combinations of the providers at the same time. Think about safe and scalable provider upgrade story:

  • TG allows provider generation
  • TF still tests the module with TerraTest

Basically, you do something like that:

generate "provider" {

  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider "azurerm" {
  version = "=${get_env("TG_PROVIDER_AZURERM_VERSION", "2.40.0")}"
  features {}
}

}

and the you can run your test in parallel setting different env variables for TG_PROVIDER_AZURERM_VERSION to test your module under different provider verssion:

  • current, current + 1
  • current, current +1, latest, latest -1
  • any combinations of the providers, basically

Running such tests in parallel with different env variable setup unlocks easy and scalable upgrade story, testing and also troubleshooting should providers have funky behaviors.

All that is harder to do with native TF, not much options to override provider setup version (unless I miss something).
Would be so great to have TerraTest support for TG, of course.

@mrwormhole
Copy link

Would be good to get sample docs for terragrunt with terratest as @pandu-bhojaraj-mf mentioned in its comments. There is literally no guide on such a simple swap out binary task

@sbgillett
Copy link

Here's a quick Terragrunt test I got working using the existing example terragrunt-example:

package test

import (
	"testing"

	"github.com/gruntwork-io/terratest/modules/terraform"
	"github.com/stretchr/testify/assert"
)

func TestTerragruntExample(t *testing.T) {
	// website::tag::2:: Construct the terraform options with default retryable errors to handle the most common
	// retryable errors in terraform testing.
	terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
		// website::tag::1:: Set the path to the Terraform code that will be tested.
		TerraformDir: "../examples/terragrunt-example",
		TerraformBinary: "terragrunt.exe", // ensure terragrunt is on your PATH, or provide the full path here
	})

	// website::tag::5:: Clean up resources with "terragrunt destroy" at the end of the test.
	defer terraform.Destroy(t, terraformOptions)

	// website::tag::3:: Run "terragrunt init" and "terragrunt apply". Fail the test if there are any errors.
	terraform.InitAndApply(t, terraformOptions)

	// website::tag::4:: Run `terragrunt output` to get the values of output variables and check they have the expected values.
	output := terraform.Output(t, terraformOptions, "output")
	assert.Equal(t, "one input another input", output)
}
  1. Ensure Terraform and Terragrunt are installed and on your PATH
  2. Install Golang and make sure this code is on your GOPATH
  3. cd test
  4. go test -v -run TestTerragruntExample

@yorinasub17
Copy link
Contributor

Hi folks, I just merged in a terragrunt example that is exposed on our site, which is going to be very similar to the one above: https://terratest.gruntwork.io/examples/ (it's unfortunately in the overflow, hidden in the dropdown)

Hopefully folks can use that going forward!

@mrwormhole
Copy link

still don't see it but thanks for the link. Screenshot would be good to find that dropdown

@yorinasub17
Copy link
Contributor

Here's a screenshot:

Screen Shot 2021-09-30 at 8 02 59 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants