github.com/swisspost/terratest@v0.0.0-20230214120104-7ec6de2e1ae0/docs/_docs/01_getting-started/quick-start.md (about)

     1  ---
     2  layout: collection-browser-doc
     3  title: Quick start
     4  category: getting-started
     5  excerpt: Learn how to start with Terratest.
     6  tags: ["quick-start"]
     7  order: 101
     8  nav_title: Documentation
     9  nav_title_link: /docs/
    10  custom_js:
    11    - examples
    12    - prism
    13  ---
    14  
    15  ## Requirements
    16  
    17  Terratest uses the Go testing framework. To use Terratest, you need to install:
    18  
    19  - [Go](https://golang.org/) (requires version >=1.18)
    20  
    21  ## Setting up your project
    22  
    23  The easiest way to get started with Terratest is to copy one of the examples and its corresponding tests from this
    24  repo. This quick start section uses a Terraform example, but check out the [Examples]({{site.baseurl}}/examples/) section for other
    25  types of infrastructure code you can test (e.g., Packer, Kubernetes, etc).
    26  
    27  1. Create an `examples` and `test` folder.
    28  
    29  1. Copy the folder including all the files from the [basic terraform example](https://github.com/gruntwork-io/terratest/tree/master/examples/terraform-basic-example/) into the `examples` folder.
    30  
    31  1. Copy the [basic terraform example test](https://github.com/gruntwork-io/terratest/blob/master/test/terraform_basic_example_test.go) into the `test` folder.
    32  
    33  1. To configure dependencies, run:
    34  
    35      ```bash
    36      cd test
    37      go mod init "<MODULE_NAME>"
    38      go mod tidy
    39      ```
    40  
    41      Where `<MODULE_NAME>` is the name of your module, typically in the format
    42      `github.com/<YOUR_USERNAME>/<YOUR_REPO_NAME>`.
    43  
    44  1. To run the tests:
    45  
    46      ```bash
    47      cd test
    48      go test -v -timeout 30m
    49      ```
    50  
    51      *(See [Timeouts and logging]({{ site.baseurl }}/docs/testing-best-practices/timeouts-and-logging/) for why the `-timeout` parameter is used.)*
    52  
    53  
    54  ## Terratest intro
    55  
    56  The basic usage pattern for writing automated tests with Terratest is to:
    57  
    58  1. Write tests using Go’s built-in [package testing](https://golang.org/pkg/testing/): you create a file ending in `_test.go` and run tests with the `go test` command. E.g., `go test my_test.go`.
    59  1. Use Terratest to execute your _real_ IaC tools (e.g., Terraform, Packer, etc.) to deploy _real_ infrastructure (e.g., servers) in a _real_ environment (e.g., AWS).
    60  1. Use the tools built into Terratest to validate that the infrastructure works correctly in that environment by making HTTP requests, API calls, SSH connections, etc.
    61  1. Undeploy everything at the end of the test.
    62  
    63  To make this sort of testing easier, Terratest provides a variety of helper functions and patterns for common infrastructure testing tasks, such as testing Terraform code, testing Packer templates, testing Docker images, executing commands on servers over SSH, making HTTP requests, working with AWS APIs, and so on.
    64  
    65  
    66  ## Example #1: Terraform "Hello, World"
    67  
    68  Let's start with the simplest possible [Terraform](https://www.terraform.io/) code, which just outputs the text, 
    69  "Hello, World" (if you’re new to Terraform, check out our [Comprehensive Guide to 
    70  Terraform](https://blog.gruntwork.io/a-comprehensive-guide-to-terraform-b3d32832baca)): 
    71   
    72  {% include examples/explorer.html example_id='terraform-hello-world' file_id='terraform_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
    73   
    74  How can you test this code to be confident it works correctly? Well, let’s think about how you would test it manually:
    75  
    76  1. Run `terraform init` and `terraform apply` to execute the code.
    77  1. When `apply` finishes, check that the output variable says, "Hello, World".
    78  1. When you're done testing, run `terraform destroy` to clean everything up.
    79   
    80  Using Terratest, you can write an automated test that performs the exact same steps! Here’s what the code looks like:
    81   
    82  {% include examples/explorer.html example_id='terraform-hello-world' file_id='test_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
    83   
    84  This code does all the steps we mentioned above, including running `terraform init`, `terraform apply`, reading the 
    85  output variable using `terraform output`, checking its value is what we expect, and running `terraform destroy` 
    86  (using [`defer`](https://blog.golang.org/defer-panic-and-recover) to run it at the end of the test, whether the test 
    87  succeeds or fails). If you put this code in a file called `terraform_hello_world_example_test.go`, you can run it by 
    88  executing `go test`, and you’ll see output that looks like this (truncated for readability):
    89  
    90  ```
    91  $ go test -v
    92  === RUN   TestTerraformHelloWorldExample
    93  Running command terraform with args [init]
    94  Initializing provider plugins...
    95  [...]
    96  Terraform has been successfully initialized!
    97  [...]
    98  Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    99  Outputs:
   100  hello_world = "Hello, World!"
   101  [...]
   102  Running command terraform with args [destroy -force -input=false]
   103  [...]
   104  Destroy complete! Resources: 2 destroyed.
   105  --- PASS: TestTerraformHelloWorldExample (149.36s)
   106  ```
   107  
   108  Success! 
   109  
   110  ## Example #2: Terraform and AWS
   111  
   112  Let's now try out a more realistic Terraform example. Here is some Terraform code that deploys a simple web server in 
   113  AWS:
   114  
   115  {% include examples/explorer.html example_id='aws-hello-world' file_id='terraform_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
   116  
   117  The code above deploys an [EC2 Instance](https://aws.amazon.com/ec2/) that is running an Ubuntu 
   118  [Amazon Machine Image (AMI)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html). To keep this example 
   119  simple, we specify a [User Data](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-api-cli) 
   120  script that, while the server is booting, fires up a dirt-simple web server that returns “Hello, World” on port 8080.
   121  
   122  How can you test this code to be confident it works correctly? Well, let’s again think about how you would test it 
   123  manually:
   124  
   125  1. Run `terraform init` and `terraform apply` to deploy the web server into your AWS account.
   126  1. When `apply` finishes, get the IP of the web server by reading the `public_ip` output variable.
   127  1. Open the IP in your web browser with port 8080 and make sure it says “Hello, World”. Note that it can take 1–2 
   128     minutes for the server to boot up, so you may have to retry a few times.
   129  1. When you’re done testing, run `terraform destroy` to clean everything up.
   130  
   131  Here's how we can automate the steps above using Terratest:
   132  
   133  {% include examples/explorer.html example_id='aws-hello-world' file_id='test_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
   134  
   135  This test code runs `terraform init` and `terraform apply`, reads the server IP using `terraform output`, makes HTTP 
   136  requests to the web server (including plenty of retries to account for the server taking time to boot), checks the HTTP
   137  response is what we expect, and then runs `terraform destroy` at the end. If you put this code in a file called 
   138  `terraform_aws_hello_world_example_test.go`, you can run just this test by passing the `-run` argument to `go test` as 
   139  follows:
   140  
   141  ```
   142  $ go test -v -run TestTerraformAwsHelloWorldExample -timeout 30m
   143  === RUN   TestTerraformAwsHelloWorldExample
   144  Running command terraform with args [init]
   145  Initializing provider plugins...
   146  [...]
   147  Terraform has been successfully initialized!
   148  [...]
   149  Running command terraform with args [apply -auto-approve]
   150  aws_instance.example: Creating...
   151    associate_public_ip_address:       "" => "<computed>"
   152    availability_zone:                 "" => "<computed>"
   153    ephemeral_block_device.#:          "" => "<computed>"
   154    instance_type:                     "" => "t2.micro"
   155    key_name:                          "" => "<computed>"
   156  [...]
   157  Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
   158  Outputs:
   159  public_ip = 52.67.41.31
   160  [...]
   161  Making an HTTP GET call to URL http://52.67.41.31:8080
   162  dial tcp 52.67.41.31:8080: getsockopt: connection refused.
   163  Sleeping for 5s and will try again.
   164  Making an HTTP GET call to URL http://52.67.41.31:8080
   165  dial tcp 52.67.41.31:8080: getsockopt: connection refused.
   166  Sleeping for 5s and will try again.
   167  Making an HTTP GET call to URL http://52.67.41.31:8080
   168  Success!
   169  [...]
   170  Running command terraform with args [destroy -force -input=false]
   171  [...]
   172  Destroy complete! Resources: 2 destroyed.
   173  --- PASS: TestTerraformAwsHelloWorldExample (149.36s)
   174  ```
   175  
   176  Success! Now, every time you make a change to this Terraform code, the test code can run and make sure your web server 
   177  works as expected.
   178  
   179  Note that in the `go test` command above, we set `-timeout 30m`. This is because Go sets a default test time out of 10
   180  minutes, and if your test take longer than that to run, Go will panic, and kill the test code part way through. This is
   181  not only annoying, but also prevents the clean up code from running (the `terraform destroy`), leaving you with lots of
   182  resources hanging in your AWS account. To prevent this, we always recommend setting a high test timeout; the test above
   183  doesn't actually take anywhere near 30 minutes (typical runtime is ~3 minutes), but we give lots of extra buffer to be
   184  extra sure that the test always has a chance to finish cleanly. 
   185  
   186  ## Example #3: Docker
   187  
   188  You can use Terratest for testing a variety of infrastructure code, not just Terraform. For example, you can use it to
   189  test your [Docker](https://www.docker.com/) images:
   190  
   191  {% include examples/explorer.html example_id='docker-hello-world' file_id='docker_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
   192  
   193  The `Dockerfile` above creates a simple Docker image that uses Ubuntu 18.04 as a base and writes the text "Hello, World!" 
   194  to a text file. At this point, you should already know the drill. First, let's think through how you'd test this 
   195  `Dockerfile` manually:
   196  
   197  1. Run `docker build` to build the Docker image.
   198  1. Run the image via `docker run`.
   199  1. Check that the running Docker container has a text file with the text "Hello, World!" in it.
   200  
   201  Here's how you can use Terratest to automate this process:  
   202  
   203  {% include examples/explorer.html example_id='docker-hello-world' file_id='test_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
   204  
   205  Instead of using Terraform helpers, this test code uses Terratest's Docker helpers to run `docker build`, `docker run`,
   206  and check the contents of the text file. As before, you can run this test using `go test`!
   207  
   208  ## Example #4: Kubernetes
   209  
   210  Terratest also provides helpers for testing your [Kubernetes](https://kubernetes.io/) code. For example, here's a 
   211  Kubernetes manifest you might want to test:
   212  
   213  {% include examples/explorer.html example_id='kubernetes-hello-world' file_id='k8s_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
   214  
   215  This manifest deploys the [Docker training webapp](https://hub.docker.com/r/training/webapp/), a simple app that 
   216  responds with the text "Hello, World!", as a Kubernetes Deployment and exposes it to the outside world on port 5000 
   217  using a `LoadBalancer`.
   218  
   219  To test this code manually, you would:
   220  
   221  1. Run `kubectl apply` to deploy the Docker training webapp.
   222  1. Use the Kubernetes APIs to figure out the endpoint to hit for the load balancer.
   223  1. Open the endpoint in your web browser on port 5000 and make sure it says “Hello, World”. Note that, depending on 
   224     your Kubernetes cluster, it could take a minute or two for the Docker container to come up, so you may have to retry 
   225     a few times.
   226  1. When you're done testing, run `kubectl delete` to clean everything up.
   227  
   228  Here's how you automate this process with Terratest:
   229  
   230  {% include examples/explorer.html example_id='kubernetes-hello-world' file_id='test_code' class='wide quick-start-examples' skip_learn_more=true skip_view_on_github=true skip_tags=true %}
   231  
   232  The test code above uses Kuberenetes helpers built into Terratest to run `kubectl apply`, wait for the service to come
   233  up, get the service endpoint, make HTTP requests to the service (with plenty of retries), check the response is what
   234  we expect, and runs `kubectl delete` at the end. You run this test with `go test` as well! 
   235  
   236  
   237  ## Give it a shot!
   238  
   239  The above is just a small taste of what you can do with [Terratest](https://github.com/gruntwork-io/terratest). To 
   240  learn more:
   241  
   242  1. Check out the [examples]({{site.baseurl}}/examples/) and the corresponding automated tests for those examples for fully working (and tested!) sample code.
   243  1. Browse through the list of [Terratest packages]({{site.baseurl}}/docs/getting-started/packages-overview/) to get a sense of all the tools available in Terratest.
   244  1. Read our [Testing Best Practices Guide]({{site.baseurl}}/docs/#testing-best-practices).
   245  1. Check out real-world examples of Terratest usage in our open source infrastructure modules: [Consul](https://github.com/hashicorp/terraform-aws-consul), [Vault](https://github.com/hashicorp/terraform-aws-vault), [Nomad](https://github.com/hashicorp/terraform-aws-nomad).
   246  
   247  Happy testing!