Skip to content
This repository has been archived by the owner on Feb 14, 2024. It is now read-only.

test: Add new test skeleton based on Terratest and add/extend tests for multiple modules #257

Merged
merged 35 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
184e1ff
Add new function in Go as test skeleton to execute Terratest and add …
sebastianczech Jan 5, 2023
146825a
Update comments in Go code
sebastianczech Jan 5, 2023
3801652
Clean code after using new test skeleton
sebastianczech Jan 9, 2023
7ec30ea
Update comment in test skeleton
sebastianczech Jan 9, 2023
dd603f8
Split Terraform code for tests of module vpc_route into main.tf, vari…
sebastianczech Jan 9, 2023
0dc9e9e
Extend module vpc_route outputs
sebastianczech Jan 9, 2023
c52bcec
Add tests for checking TGW as next hop and prepared code for othe typ…
sebastianczech Jan 9, 2023
7935bed
Add tests for checking NATGW and GWLB endpoints as next hop
sebastianczech Jan 9, 2023
bf4d223
Refactor tests checking outputs from bootstrap module
sebastianczech Jan 10, 2023
d44a164
Extend test skeleton by adding messages for asserts
sebastianczech Jan 10, 2023
c7e109c
Update assert package and add function in skeleton to assert errors
sebastianczech Jan 10, 2023
22d0e3f
Tests for checking errors while running Terraform plan
sebastianczech Jan 10, 2023
dc47535
2 kind of deployments with vpc_route module - full with TGW, NAT, GWL…
sebastianczech Jan 10, 2023
3a722f6
Clean tests codes for bootstrap module
sebastianczech Jan 10, 2023
19d1365
Simplify terraform_minimum.tfvars
sebastianczech Jan 10, 2023
274a52e
Add check function to test skeleton
sebastianczech Jan 11, 2023
5fdac5c
Tests for Panorama module
sebastianczech Jan 11, 2023
e13fee2
Verify bucket access in module bootstrap tests
sebastianczech Jan 11, 2023
7eeeff0
Small refactors (comments, provider versions)
sebastianczech Jan 11, 2023
35bf6c9
Update README
sebastianczech Jan 12, 2023
7cb29ea
2 tests for transit gateway module
sebastianczech Jan 12, 2023
ba5c9cc
Format code for module transit_gateway
sebastianczech Jan 13, 2023
c8f644f
Add ALB test coverage and refactor skeleton (#275)
pimielowski Jan 17, 2023
692f78f
Change bash path in scripts/install.sh and scripts/run.sh
sebastianczech Jan 17, 2023
ca61a08
Add required_providers for tls
sebastianczech Jan 17, 2023
60925eb
test: Test for modules transit_gateway_attachment, transit_gateway_pe…
sebastianczech Jan 17, 2023
047d3c3
test: Refactor tests skeleton and tests, small adjustments in modules…
sebastianczech Jan 18, 2023
83903ec
Restore changes in panorama module, fix example only to pass target_k…
sebastianczech Jan 19, 2023
a3034d9
test: Use ResourceChangesMap to check planned changes, do not use reg…
sebastianczech Jan 19, 2023
11d6348
Remove changes in examples and modules
sebastianczech Jan 24, 2023
5785dbc
Merge branch 'main' into test-skeleton-165
sebastianczech Jan 25, 2023
bbadb67
Introduce enum for assert operations (instead of strings)
sebastianczech Jan 25, 2023
1b5fb0a
Merge branch 'main' into test-skeleton-165
sebastianczech Jan 26, 2023
e83873d
Bump up minimum Terraform version to 1.0.0 in tests
sebastianczech Jan 26, 2023
32999e3
test: Test skeleton diagram and integrations tests for module vmserie…
sebastianczech Feb 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
.terragrunt-cache
.vscode
.idea

**/test_report.html
# Palo auth codes
authcodes
# Crash log files
Expand Down
11 changes: 9 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@ module github.com/PaloAltoNetworks/terraform-aws-vmseries-modules
go 1.14

require (
github.com/gruntwork-io/terratest v0.35.7
github.com/apex/log v1.9.0
github.com/aws/aws-sdk-go-v2 v1.17.3
github.com/aws/aws-sdk-go-v2/config v1.18.8
github.com/aws/aws-sdk-go-v2/service/sts v1.18.0 // indirect
github.com/gruntwork-io/terratest v0.41.7
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/terraform-json v0.14.0
github.com/stretchr/testify v1.4.0
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/cobra v1.6.1 // indirect
github.com/stretchr/testify v1.8.1
github.com/vakenbolt/go-test-report v0.9.3 // indirect
github.com/zclconf/go-cty v1.11.0 // indirect
)
1,034 changes: 884 additions & 150 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion scripts/install.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/bin/bash

# install.sh - prepare the dependencies for the run.sh
#
Expand Down
2 changes: 1 addition & 1 deletion scripts/run.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/bin/bash

# run.sh - Run the usual pre-commit checks.

Expand Down
27 changes: 27 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Quick start

Testing Terraform modules:
1. Install required binaries:
* Terraform at the specific version that you'd like to test: https://developer.hashicorp.com/terraform
* Go at the latest 1.* version: https://golang.org/
2. Configuration authentication settings e.g. use https://github.com/Nike-Inc/gimme-aws-creds or set ``AWS_REGION`` environment variable and also ``AWS_ACCESS_KEY_ID``, ``AWS_SECRET_ACCESS_KEY``, or similar.
3. Get ``terratest`` package by running command:
```bash
go get -u github.com/gruntwork-io/terratest
```
4. Execute test for module using commands e.g for ``bootstrap`` module:
```bash
cd tests/bootstrap
go test -v -timeout 30m -count=1
```

Run all test:

```bash
go test -timeout 130m ./... -json | go-test-report
```
Comments:
* Do not however run `go test -v .` or similar. Specifying a package (that extra dot) enables caching, which is incompatible with Terraform.
* We use go-test-report to create html reports for tests, check https://github.com/vakenbolt/go-test-report for more information
* Cloud resources are destroyed automatically after the test, no cleanup is normally required.
* VScode users should keep `Go: Test On Save` at the default false value, and not set to true. This option is spelled `go.testOnSave` in settings.json.
102 changes: 102 additions & 0 deletions tests/alb/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
## VPC

module "security_vpc" {
source = "../../modules/vpc"

name = "${var.name_prefix}-vpc"
cidr_block = var.security_vpc_cidr
security_groups = var.security_vpc_security_groups
create_internet_gateway = true
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
}

module "security_subnet_sets" {
source = "../../modules/subnet_set"

for_each = toset(distinct([for _, v in var.security_vpc_subnets : v.set]))

name = each.key
vpc_id = module.security_vpc.id
has_secondary_cidrs = module.security_vpc.has_secondary_cidrs
cidrs = { for k, v in var.security_vpc_subnets : k => v if v.set == each.key }
}

locals {
security_vpc_routes = concat(
[for cidr in ["app_vm", "app_lb"] :
{
subnet_key = cidr
next_hop_set = module.security_vpc.igw_as_next_hop_set
to_cidr = "0.0.0.0/0"
}
]
)
}
module "security_vpc_routes" {
for_each = { for route in local.security_vpc_routes : "${route.subnet_key}_${route.to_cidr}" => route }
source = "../../modules/vpc_route"

route_table_ids = module.security_subnet_sets[each.value.subnet_key].unique_route_table_ids
to_cidr = each.value.to_cidr
next_hop_set = each.value.next_hop_set
}

## ALB

module "public_alb" {
source = "../../modules/alb"

lb_name = replace("${var.name_prefix}${var.application_lb_name}", "_", "-")
subnets = { for k, v in module.security_subnet_sets["app_vm"].subnets : k => { id = v.id } }
vpc_id = module.security_vpc.id
security_groups = [module.security_vpc.security_group_ids["app_vm"]]
rules = var.application_lb_rules
targets = { for k, v in var.app_vms : k => aws_instance.app_vm[k].private_ip }

tags = var.global_tags
}


### app EC2 instance ###

data "aws_ami" "this" {
most_recent = true # newest by time, not by version number

filter {
name = "name"
values = ["bitnami-nginx-1.21*-linux-debian-10-x86_64-hvm-ebs-nami"]
# The wildcard '*' causes re-creation of the whole EC2 instance when a new image appears.
}

owners = ["979382823631"] # bitnami = 979382823631
}

resource "tls_private_key" "random_ssh_key" {
algorithm = "RSA"
rsa_bits = 4096
}

resource "aws_key_pair" "random_ssh_key_pair" {
key_name = var.key_pair_name
public_key = tls_private_key.random_ssh_key.public_key_openssh
}

resource "aws_instance" "app_vm" {
for_each = var.app_vms

ami = data.aws_ami.this.id
instance_type = var.app_vm_type
key_name = aws_key_pair.random_ssh_key_pair.key_name
subnet_id = module.security_subnet_sets["app_vm"].subnets[each.value.az].id
vpc_security_group_ids = [module.security_vpc.security_group_ids["app_vm"]]
tags = merge({ Name = "${var.name_prefix}${each.key}" }, var.global_tags)
associate_public_ip_address = true

}

data "aws_network_interface" "bar" {
for_each = var.app_vms
id = aws_instance.app_vm[each.key].primary_network_interface_id
}
93 changes: 93 additions & 0 deletions tests/alb/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package main

import (
"log"
"testing"

"github.com/PaloAltoNetworks/terraform-aws-vmseries-modules/tests/internal/helpers"
"github.com/PaloAltoNetworks/terraform-aws-vmseries-modules/tests/internal/testskeleton"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/terraform"
)

func TestALBOutputAndConectivitiyWithFullTFVars(t *testing.T) {

// define variables for Terraform
namePrefix := "terratest-alb-"

// define options for Terraform
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: ".",
VarFiles: []string{"terraform_full.tfvars"},
Vars: map[string]interface{}{
"name_prefix": namePrefix,
},
Logger: logger.Default,
Lock: true,
Upgrade: true,
SetVarsAfterVarFiles: true,
})

destroyFunc := func() {
terraform.Destroy(t, terraformOptions)
}
defer destroyFunc()
terraformOptions = testskeleton.DeployInfraNoCheckOutputsNoDestroy(t, terraformOptions)

albName := terraform.Output(t, terraformOptions, "alb_name")
log.Printf("Alb_name = %s", albName)

assertList := []testskeleton.AssertExpression{
// check if the ALB is created with correct FQDN
{
OutputName: "alb_name",
Operation: testskeleton.NotEmpty,
},
// check if the ALB is created with correct FQDN
{
OutputName: "alb_name",
Operation: testskeleton.StartsWith,
ExpectedValue: namePrefix,
},
// check communication with app
{
Operation: testskeleton.CheckFunctionWithValue,
Check: helpers.CheckHttpGetWebApp,
TestedValue: "http://" + albName + "/",
},
}
testskeleton.AssertOutputs(t, terraformOptions, assertList)

}

func TestALBOutputWithMinimumTFVars(t *testing.T) {

// define variables for Terraform
namePrefix := "terratest-alb-"
// define options for Terraform
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: ".",
VarFiles: []string{"terraform_minimum.tfvars"},
Vars: map[string]interface{}{
"name_prefix": namePrefix,
},
Logger: logger.Default,
Lock: true,
Upgrade: true,
SetVarsAfterVarFiles: true,
})
assertList := []testskeleton.AssertExpression{
// check if the ALB is created with correct FQDN
{
OutputName: "alb_name",
Operation: testskeleton.NotEmpty,
},
// check if the ALB is created with correct FQDN
{
OutputName: "alb_name",
Operation: testskeleton.StartsWith,
ExpectedValue: namePrefix,
},
}
testskeleton.DeployInfraCheckOutputs(t, terraformOptions, assertList)
}
7 changes: 7 additions & 0 deletions tests/alb/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "alb_name" {
value = module.public_alb.lb_fqdn
}

output "vms_public_ips" {
value = [for k, v in var.app_vms : aws_instance.app_vm[k].public_ip]
}
53 changes: 53 additions & 0 deletions tests/alb/terraform_full.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
global_tags = {
ManagedBy = "Terraform"
Application = "Palo Alto Networks VM-Series NGFW Automatic Tests"
}
region = "us-east-1"
name_prefix = "test-vpc-route-"

security_vpc_cidr = "10.100.0.0/16"
security_vpc_subnets = {
"10.100.0.0/24" = { az = "us-east-1a", set = "app_vm" }
"10.100.2.0/24" = { az = "us-east-1b", set = "app_vm" }
"10.100.3.0/24" = { az = "us-east-1a", set = "app_lb" }
"10.100.4.0/24" = { az = "us-east-1b", set = "app_lb" }
}
security_vpc_security_groups = {
app_vm = {
name = "app_vm"
rules = {
all_outbound = {
description = "Permit ALL outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ssh = {
description = "Permit SSH inbound"
type = "ingress", from_port = "80", to_port = "80", protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}

app_vms = {
"app_vm01" = { az = "us-east-1a" }
"app_vm02" = { az = "us-east-1b" }
}

application_lb_rules = {
"main-welcome-page" = {
protocol = "HTTP"
health_check_port = "80"
health_check_matcher = "200"
health_check_path = "/"
health_check_interval = 10
listener_rules = {
"1" = {
target_protocol = "HTTP"
target_port = 80
path_pattern = ["/"]
}
}
}
}
31 changes: 31 additions & 0 deletions tests/alb/terraform_minimum.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
global_tags = {
ManagedBy = "Terraform"
Application = "Palo Alto Networks VM-Series NGFW Automatic Tests"
}
region = "us-east-1"
name_prefix = "test-vpc-route-"

security_vpc_cidr = "10.100.0.0/16"
security_vpc_subnets = {
"10.100.0.0/24" = { az = "us-east-1a", set = "app_vm" }
"10.100.2.0/24" = { az = "us-east-1b", set = "app_vm" }
"10.100.3.0/24" = { az = "us-east-1a", set = "app_lb" }
"10.100.4.0/24" = { az = "us-east-1b", set = "app_lb" }
}
security_vpc_security_groups = {
app_vm = {
name = "app_vm"
rules = {
all_outbound = {
description = "Permit ALL outbound"
type = "egress", from_port = "0", to_port = "0", protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ssh = {
description = "Permit SSH inbound"
type = "ingress", from_port = "80", to_port = "80", protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
Loading