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

Add ALB test coverage and refactor skeleton #275

Merged
merged 6 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
7 changes: 7 additions & 0 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/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/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
)
69 changes: 67 additions & 2 deletions go.sum

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions modules/alb/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ resource "aws_s3_bucket_policy" "this" {
}
# ######################## #

## Add communication to ALB with ephemeral port

resource "aws_security_group_rule" "alb_att" {

from_port = 0
protocol = "all"
source_security_group_id = var.security_groups[0]
security_group_id = var.security_groups[0]
to_port = 0
type = "ingress"
}

# ## Application Load Balancer ##
resource "aws_lb" "this" {
name = var.lb_name
Expand Down
1 change: 1 addition & 0 deletions scripts/install.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ echo "Also, the newest release: $(curl -s https://api.github.com/repos/tfsec/tfs
echo "Also, the newest release: $(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")"

python3 -m pip install -r requirements.txt

5 changes: 3 additions & 2 deletions scripts/run.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

set -euo pipefail

pre-commit run --all-files terraform_fmt
pre-commit run --all-files terraform_docs
pre-commit run --all-files terraform_fmt
pre-commit run --all-files terraform_docs
pre-commit run --all-files terraform_tflint

8 changes: 7 additions & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ 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 90m -count=1
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
}
92 changes: 92 additions & 0 deletions tests/alb/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package main

import (
"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"
"log"
"testing"
)

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.InitAndApplyOnlyWithoutDelete(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: "NotEmpty",
},
// check if the ALB is created with correct FQDN
{
OutputName: "alb_name",
Operation: "StartsWith",
ExpectedValue: namePrefix,
},
// check communication with app
{
Operation: "CheckFunctionWithValue",
Check: helpers.CheckHttpGetWebUiLoginPage,
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: "NotEmpty",
},
// check if the ALB is created with correct FQDN
{
OutputName: "alb_name",
Operation: "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