Skip to content

Commit

Permalink
integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
Ujstor committed Jun 20, 2024
1 parent b761b7e commit e796707
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 161 deletions.
135 changes: 5 additions & 130 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,138 +52,13 @@ go test -v -timeout 30m -run TestHelloWorldAppExample
go test -v -timeout 30m -parallel 2
```

## Dir structure
### Integration tests

For testing multiple modules in the staging environment, extract the state S3 config into a separate file.
This will prevent overwriting the state file and can be used manually:

```bash
[4.0K] ./
├── [4.0K] global/
│ ├── [4.0K] ghAction/
│ │ ├── [1.6K] main.tf
│ │ ├── [ 535] outputs.tf
│ │ ├── [ 411] terraform.tf
│ │ ├── [ 992] tf-apply.yml
│ │ └── [ 308] variables.tf
│ ├── [4.0K] iam/
│ │ ├── [1.2K] main.tf
│ │ ├── [1.7K] outputs.tf
│ │ ├── [ 375] terraform.tf
│ │ └── [ 472] variables.tf
│ └── [4.0K] s3/
│ ├── [ 930] main.tf
│ ├── [ 259] outputs.tf
│ ├── [ 374] terraform.tf
│ └── [ 330] variables.tf
├── [4.0K] modules/
│ ├── [4.0K] examples/
│ │ ├── [4.0K] alb/
│ │ │ ├── [ 207] dependencies.tf
│ │ │ ├── [ 177] main.tf
│ │ │ ├── [ 382] outputs.tf
│ │ │ ├── [ 320] terraform.tf
│ │ │ ├── [5.9K] terraform.tfstate
│ │ │ ├── [ 181] terraform.tfstate.backup
│ │ │ └── [ 116] variables.tf
│ │ ├── [4.0K] asg/
│ │ │ └── [4.0K] one-instance/
│ │ │ ├── [ 439] dependencies.tf
│ │ │ ├── [ 370] main.tf
│ │ │ ├── [ 111] outputs.tf
│ │ │ ├── [ 321] terraform.tf
│ │ │ └── [ 79] variables.tf
│ │ └── [4.0K] hello-world-app/
│ │ └── [4.0K] standalone/
│ │ ├── [ 721] dependencies.tf
│ │ ├── [ 422] main.tf
│ │ ├── [ 109] outputs.tf
│ │ ├── [ 319] terraform.tf
│ │ ├── [ 29K] terraform.tfstate
│ │ ├── [1.0K] terraform.tfstate.backup
│ │ └── [ 625] variables.tf
│ ├── [4.0K] modules/
│ │ ├── [4.0K] cluster/
│ │ │ └── [4.0K] asg-rolling-deploy/
│ │ │ ├── [ 80] dependencies.tf
│ │ │ ├── [3.5K] main.tf
│ │ │ ├── [ 274] outputs.tf
│ │ │ ├── [ 159] terraform.tf
│ │ │ └── [1.9K] variables.tf
│ │ ├── [4.0K] data-stores/
│ │ │ └── [4.0K] mysql/
│ │ │ ├── [ 669] main.tf
│ │ │ ├── [ 338] outputs.tf
│ │ │ ├── [ 159] terraform.tf
│ │ │ └── [1.3K] variables.tf
│ │ ├── [4.0K] eks-cluster/
│ │ │ ├── [ 233] dependencies.tf
│ │ │ ├── [2.3K] main.tf
│ │ │ ├── [ 517] outputs.tf
│ │ │ ├── [ 159] terraform.tf
│ │ │ └── [ 583] variables.tf
│ │ ├── [4.0K] k8s/
│ │ │ ├── [1.3K] main.tf
│ │ │ ├── [ 368] outputs.tf
│ │ │ ├── [ 159] terraform.tf
│ │ │ └── [ 662] variables.tf
│ │ ├── [4.0K] networking/
│ │ │ └── [4.0K] alb/
│ │ │ ├── [1.2K] main.tf
│ │ │ ├── [ 367] outputs.tf
│ │ │ ├── [ 158] terraform.tf
│ │ │ └── [ 187] variables.tf
│ │ └── [4.0K] services/
│ │ └── [4.0K] hello-world-app/
│ │ ├── [ 797] dependencies.tf
│ │ ├── [1.4K] main.tf
│ │ ├── [ 389] outputs.tf
│ │ ├── [ 159] terraform.tf
│ │ ├── [ 168] user-data.sh
│ │ └── [2.0K] variables.tf
│ └── [4.0K] test/
│ ├── [ 870] alb_example_test.go
│ ├── [2.6K] go.mod
│ ├── [ 94K] go.sum
│ └── [1.0K] hello_world_test.go
├── [4.0K] packer/
│ ├── [ 576] webserver.json
│ └── [ 724] webserver.json.pkr.hcl
├── [4.0K] prod/
│ ├── [4.0K] data-stores/
│ │ └── [4.0K] mysql/
│ │ ├── [ 626] main.tf
│ │ ├── [ 783] output.tf
│ │ ├── [ 712] terraform.tf
│ │ └── [ 265] variables.tf
│ └── [4.0K] services/
│ ├── [4.0K] eks-cluster/
│ │ ├── [ 81] dependencies.tf
│ │ ├── [ 693] main.tf
│ │ ├── [ 257] outputs.tf
│ │ └── [ 776] terraform.tf
│ └── [4.0K] hello-world-app/
│ ├── [ 202] dependencies.tf
│ ├── [ 572] main.tf
│ ├── [ 111] outputs.tf
│ └── [ 538] terraform.tf
├── [4.0K] stage/
│ ├── [4.0K] data-stores/
│ │ └── [4.0K] mysql/
│ │ ├── [ 389] main.tf
│ │ ├── [ 337] output.tf
│ │ ├── [ 648] terraform.tf
│ │ └── [ 266] variables.tf
│ └── [4.0K] services/
│ ├── [4.0K] hello-world-app/
│ │ ├── [ 202] dependencies.tf
│ │ ├── [ 587] main.tf
│ │ ├── [ 109] outputs.tf
│ │ └── [ 656] terraform.tf
│ └── [4.0K] k8s/
│ ├── [ 420] main.tf
│ ├── [ 127] outputs.tf
│ └── [ 571] terraform.tf
├── [1.0K] LICENSE.txt
├── [5.7K] README.md
└── [ 180] terraform.tfstate
terraform init -backend-config=backend.hcl
```

## License
Expand Down
2 changes: 1 addition & 1 deletion modules/modules/services/hello-world-app/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ variable "db_remote_state_key" {
variable "server_text" {
description = "Text the web server should return"
type = string
default = "Hello World tag 0.1.1"
default = "Hello, World"
}

variable "environment" {
Expand Down
88 changes: 88 additions & 0 deletions modules/test/hello_world_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package test

import (
"fmt"
"strings"
"testing"
"time"

"github.com/gruntwork-io/terratest/modules/http-helper"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
)

const (
dbDirStage = "../../stage/data-stores/mysql/"
appDirStage = "../../stage/services/hello-world-app/"
)

func TestHelloWorldAppStage(t *testing.T) {
t.Parallel()

dbOpts := createDbOpts(t, dbDirStage)
defer terraform.Destroy(t, dbOpts)
terraform.InitAndApply(t, dbOpts)

helloOpts := createHelloOpts(dbOpts, appDirStage)
defer terraform.Destroy(t, helloOpts)
terraform.InitAndApply(t, helloOpts)

validateHelloApp(t, helloOpts)
}

func createDbOpts(t *testing.T, terraformDir string) *terraform.Options {
uniqueId := random.UniqueId()
bucketTesting := "tf-state-ujstor"
bucketRegionTesting := "us-east-1"
dynamodbTable := "terraform-state-locks"

dbStateKey := fmt.Sprintf("%s/%s/terraform.tfstate", t.Name(), uniqueId)

return &terraform.Options{
TerraformDir: terraformDir,

Vars: map[string]interface{}{
"db_name": fmt.Sprintf("testdb%s", uniqueId),
"db_username": "admin",
"db_password": "password",
},
BackendConfig: map[string]interface{}{
"bucket": bucketTesting,
"region": bucketRegionTesting,
"key": dbStateKey,
"dynamodb_table": dynamodbTable,
"encrypt": true,
},
}
}

func createHelloOpts(dbOpts *terraform.Options, terraformDir string) *terraform.Options {
return &terraform.Options{
TerraformDir: terraformDir,

Vars: map[string]interface{}{
"db_remote_state_bucket": dbOpts.BackendConfig["bucket"],
"db_remote_state_key": dbOpts.BackendConfig["key"],
"environment": dbOpts.Vars["db_name"],
},
}
}

func validateHelloApp(t *testing.T, helloOpts *terraform.Options) {
albDnsName := terraform.OutputRequired(t, helloOpts, "alb_dns_name")
url := fmt.Sprintf("http://%s", albDnsName)
maxRetries := 10
timeBetweenRetries := 10 * time.Second

http_helper.HttpGetWithRetryWithCustomValidation(
t,
url,
nil,
maxRetries,
timeBetweenRetries,
func(status int, body string) bool {
return status == 200 &&
strings.Contains(body, "Hello, World")
},
)
}
34 changes: 17 additions & 17 deletions stage/data-stores/mysql/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions stage/data-stores/mysql/backend.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bucket = "tf-state-ujstor"
key = "stage/data-stores/mysql/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"
encrypt = true
6 changes: 3 additions & 3 deletions stage/data-stores/mysql/main.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module "mysql_db_stage" {
source = "github.com/ujstor/aws-terraform//modules/modules/data-stores/mysql?ref=v0.1.3"
# source = "../../../modules/modules/data-stores/mysql"
# source = "github.com/ujstor/aws-terraform//modules/modules/data-stores/mysql?ref=v0.1.3"
source = "../../../modules/modules/data-stores/mysql"

providers = {
aws = aws.stage
}

identifier_prefix = "stage-mysql"
instance_class = "db.t3.micro"
db_name = "stageDB"

db_name = var.db_name
db_username = var.db_username
db_password = var.db_password
}
Expand Down
5 changes: 0 additions & 5 deletions stage/data-stores/mysql/terraform.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
terraform {
backend "s3" {
bucket = "tf-state-ujstor"
key = "stage/data-stores/mysql/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"
encrypt = true
}
required_providers {
aws = {
Expand Down
5 changes: 5 additions & 0 deletions stage/data-stores/mysql/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ variable "db_password" {
sensitive = true
}

variable "db_name" {
description = "Name of the database to create"
type = string
default = "stageDb"
}
5 changes: 5 additions & 0 deletions stage/services/hello-world-app/backend.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bucket = "tf-state-ujstor"
key = "stage/services/webserver-cluster/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"
encrypt = true
10 changes: 5 additions & 5 deletions stage/services/hello-world-app/main.tf
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
module "hello-world-app" {
source = "github.com/ujstor/aws-terraform//modules/modules/services/hello-world-app?ref=v0.1.3"
# source = "../../../modules/modules/services/hello-world-app/"
# source = "github.com/ujstor/aws-terraform//modules/modules/services/hello-world-app?ref=v0.1.3"
source = "../../../modules/modules/services/hello-world-app/"

providers = {
aws = aws.stage
}

environment = "stage"
environment = var.environment
image_id = data.aws_ami.ubuntu.id
instance_type = "t2.micro"

db_remote_state_bucket = "tf-state-ujstor"
db_remote_state_key = "stage/data-stores/mysql/terraform.tfstate"
db_remote_state_bucket = var.db_remote_state_bucket
db_remote_state_key = var.db_remote_state_key

min_size = 2
max_size = 5
Expand Down
15 changes: 15 additions & 0 deletions stage/services/hello-world-app/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
variable "environment" {
description = "The name of the environment we're deploying to"
type = string
default = "stage"
}

variable "db_remote_state_bucket" {
description = "The name of the S3 bucket for the database's remote state"
type = string
}

variable "db_remote_state_key" {
description = "The path for the database's remote state in S3"
type = string
}

0 comments on commit e796707

Please sign in to comment.