-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sample): Add samples how to use test skeleton with VM-Series mod…
…ules (#2)
- Loading branch information
1 parent
1681317
commit b32df3d
Showing
34 changed files
with
1,837 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# This is a minimal list, OK to add things per repo | ||
# mac specific | ||
.DS_Store | ||
.ansible | ||
.azure/ | ||
.bash_history | ||
# don't check storage creds into GH | ||
.boto | ||
.cache | ||
*.code-workspace | ||
# may contain gcloud files | ||
.config | ||
.gitconfig | ||
.local | ||
# .netrc contains secrets for service tokens | ||
.netrc | ||
*.plan | ||
.sentinel | ||
# .ssh dir may contain private keys | ||
.ssh | ||
.terrascan | ||
*.pem | ||
.pem | ||
# Terraform dot files | ||
.terraform | ||
.terraform.lock.hcl | ||
.terraformrc | ||
**/.terraform/* | ||
.terraform.d | ||
*.tfstate | ||
*.tfstate.* | ||
.terragrunt-cache | ||
.vscode | ||
.idea | ||
**/test_report.html | ||
# Palo auth codes | ||
authcodes | ||
# Crash log files | ||
crash.log | ||
credentials.json | ||
# Palo specific | ||
init-cfg.txt | ||
temp | ||
terraform.rc | ||
tmp | ||
# Auto variables | ||
terraform.tfvars | ||
terraform.tfvars.json | ||
*.auto.tfvars | ||
*.auto.tfvars.json | ||
modules/asg/lambda_payload.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
### GENERAL | ||
region = "eu-central-1" # TODO: update here | ||
name_prefix = "example-" # TODO: update here | ||
|
||
global_tags = { | ||
ManagedBy = "terraform" | ||
Application = "Palo Alto Networks VM-Series NGFW" | ||
Owner = "PS Team" | ||
} | ||
|
||
ssh_key_name = "example-ssh-key" # TODO: update here | ||
|
||
### VPC | ||
vpcs = { | ||
# Do not use `-` in key for VPC as this character is used in concatation of VPC and subnet for module `subnet_set` in `main.tf` | ||
security_vpc = { | ||
name = "security-vpc" | ||
cidr = "10.100.0.0/16" | ||
nacls = {} | ||
security_groups = { | ||
vmseries_mgmt = { | ||
name = "vmseries_mgmt" | ||
rules = { | ||
all_outbound = { | ||
description = "Permit All traffic outbound" | ||
type = "egress", from_port = "0", to_port = "0", protocol = "-1" | ||
cidr_blocks = ["0.0.0.0/0"] | ||
} | ||
https = { | ||
description = "Permit HTTPS" | ||
type = "ingress", from_port = "443", to_port = "443", protocol = "tcp" | ||
cidr_blocks = ["0.0.0.0/0"] # TODO: update here (replace 0.0.0.0/0 by your IP range) | ||
} | ||
ssh = { | ||
description = "Permit SSH" | ||
type = "ingress", from_port = "22", to_port = "22", protocol = "tcp" | ||
cidr_blocks = ["0.0.0.0/0"] # TODO: update here (replace 0.0.0.0/0 by your IP range) | ||
} | ||
} | ||
} | ||
} | ||
subnets = { | ||
# Do not modify value of `set=`, it is an internal identifier referenced by main.tf | ||
# Value of `nacl` must match key of objects stored in `nacls` | ||
"10.100.0.0/24" = { az = "eu-central-1a", set = "mgmt", nacl = null } | ||
} | ||
routes = { | ||
# Value of `vpc_subnet` is built from key of VPCs concatenate with `-` and key of subnet in format: `VPCKEY-SUBNETKEY` | ||
# Value of `next_hop_key` must match keys use to create TGW attachment, IGW, GWLB endpoint or other resources | ||
# Value of `next_hop_type` is internet_gateway, nat_gateway, transit_gateway_attachment or gwlbe_endpoint | ||
mgmt_default = { | ||
vpc_subnet = "security_vpc-mgmt" | ||
to_cidr = "0.0.0.0/0" | ||
next_hop_key = "security_vpc" | ||
next_hop_type = "internet_gateway" | ||
} | ||
} | ||
} | ||
} | ||
|
||
### VM-SERIES | ||
vmseries = { | ||
vmseries = { | ||
instances = { | ||
"01" = { az = "eu-central-1a" } | ||
} | ||
|
||
# Value of `panorama-server`, `auth-key`, `dgname`, `tplname` can be taken from plugin `sw_fw_license` | ||
bootstrap_options = { | ||
mgmt-interface-swap = "disable" | ||
plugin-op-commands = "aws-gwlb-inspect:enable,aws-gwlb-overlay-routing:enable" # TODO: update here | ||
dhcp-send-hostname = "no" # TODO: update here | ||
dhcp-send-client-id = "no" # TODO: update here | ||
dhcp-accept-server-hostname = "no" # TODO: update here | ||
dhcp-accept-server-domain = "no" # TODO: update here | ||
} | ||
|
||
panos_version = "10.2.3" # TODO: update here | ||
ebs_kms_id = "alias/aws/ebs" # TODO: update here | ||
|
||
# Value of `vpc` must match key of objects stored in `vpcs` | ||
vpc = "security_vpc" | ||
|
||
interfaces = { | ||
mgmt = { | ||
device_index = 0 | ||
private_ip = "10.100.0.4" | ||
security_group = "vmseries_mgmt" | ||
vpc_subnet = "security_vpc-mgmt" | ||
create_public_ip = true | ||
source_dest_check = true | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
### VPCS ### | ||
|
||
module "vpc" { | ||
source = "github.com/PaloAltoNetworks/terraform-aws-vmseries-modules//modules/vpc" | ||
|
||
for_each = var.vpcs | ||
|
||
name = "${var.name_prefix}${each.value.name}" | ||
cidr_block = each.value.cidr | ||
nacls = each.value.nacls | ||
security_groups = each.value.security_groups | ||
create_internet_gateway = true | ||
enable_dns_hostnames = true | ||
enable_dns_support = true | ||
instance_tenancy = "default" | ||
} | ||
|
||
### SUBNETS ### | ||
|
||
module "subnet_sets" { | ||
for_each = toset(flatten([for _, v in { for vk, vv in var.vpcs : vk => distinct([for sk, sv in vv.subnets : "${vk}-${sv.set}"]) } : v])) | ||
source = "github.com/PaloAltoNetworks/terraform-aws-vmseries-modules//modules/subnet_set" | ||
|
||
name = split("-", each.key)[1] | ||
vpc_id = module.vpc[split("-", each.key)[0]].id | ||
has_secondary_cidrs = module.vpc[split("-", each.key)[0]].has_secondary_cidrs | ||
nacl_associations = { | ||
for i in flatten([ | ||
for vk, vv in var.vpcs : [ | ||
for sk, sv in vv.subnets : | ||
{ | ||
az : sv.az, | ||
nacl_id : lookup(module.vpc[split("-", each.key)[0]].nacl_ids, sv.nacl, null) | ||
} if sv.nacl != null && each.key == "${vk}-${sv.set}" | ||
]]) : i.az => i.nacl_id | ||
} | ||
cidrs = { | ||
for i in flatten([ | ||
for vk, vv in var.vpcs : [ | ||
for sk, sv in vv.subnets : | ||
{ | ||
cidr : sk, | ||
subnet : sv | ||
} if each.key == "${vk}-${sv.set}" | ||
]]) : i.cidr => i.subnet | ||
} | ||
} | ||
|
||
### ROUTES ### | ||
|
||
locals { | ||
vpc_routes = flatten(concat([ | ||
for vk, vv in var.vpcs : [ | ||
for rk, rv in vv.routes : { | ||
subnet_key = rv.vpc_subnet | ||
to_cidr = rv.to_cidr | ||
next_hop_set = ( | ||
rv.next_hop_type == "internet_gateway" ? module.vpc[rv.next_hop_key].igw_as_next_hop_set : null | ||
) | ||
} | ||
] | ||
])) | ||
} | ||
|
||
module "vpc_routes" { | ||
for_each = { for route in local.vpc_routes : "${route.subnet_key}_${route.to_cidr}" => route } | ||
source = "github.com/PaloAltoNetworks/terraform-aws-vmseries-modules//modules/vpc_route" | ||
|
||
route_table_ids = module.subnet_sets[each.value.subnet_key].unique_route_table_ids | ||
to_cidr = each.value.to_cidr | ||
next_hop_set = each.value.next_hop_set | ||
} | ||
|
||
### IAM ROLES AND POLICIES ### | ||
|
||
resource "aws_iam_role" "vm_series_ec2_iam_role" { | ||
name = "${var.name_prefix}vmseries" | ||
assume_role_policy = <<EOF | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Effect": "Allow", | ||
"Action": "sts:AssumeRole", | ||
"Principal": {"Service": "ec2.amazonaws.com"} | ||
} | ||
] | ||
} | ||
EOF | ||
} | ||
|
||
resource "aws_iam_role_policy" "vm_series_ec2_iam_policy" { | ||
role = aws_iam_role.vm_series_ec2_iam_role.id | ||
policy = <<EOF | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": [ | ||
"cloudwatch:PutMetricAlarm", | ||
"cloudwatch:GetMetricData", | ||
"cloudwatch:PutMetricData", | ||
"cloudwatch:ListMetrics", | ||
"cloudwatch:DescribeAlarms", | ||
"logs:CreateLogGroup" | ||
], | ||
"Resource": [ | ||
"*" | ||
], | ||
"Effect": "Allow" | ||
} | ||
] | ||
} | ||
EOF | ||
} | ||
|
||
resource "aws_iam_instance_profile" "vm_series_iam_instance_profile" { | ||
|
||
name = "${var.name_prefix}vmseries_instance_profile" | ||
role = aws_iam_role.vm_series_ec2_iam_role.name | ||
} | ||
|
||
### VM-Series INSTANCES | ||
|
||
locals { | ||
vmseries_instances = flatten([for kv, vv in var.vmseries : [for ki, vi in vv.instances : { group = kv, instance = ki, az = vi.az, common = vv }]]) | ||
|
||
bootstrap_options = { for i, j in var.vmseries : i => [ | ||
for k, v in j.bootstrap_options : "${k}=${v}" | ||
] } | ||
} | ||
|
||
module "vmseries" { | ||
for_each = { for vmseries in local.vmseries_instances : "${vmseries.group}-${vmseries.instance}" => vmseries } | ||
source = "github.com/PaloAltoNetworks/terraform-aws-vmseries-modules//modules/vmseries" | ||
|
||
name = "${var.name_prefix}${each.key}" | ||
vmseries_version = each.value.common.panos_version | ||
|
||
interfaces = { | ||
for k, v in each.value.common.interfaces : k => { | ||
device_index = v.device_index | ||
private_ips = [v.private_ip] | ||
security_group_ids = try([module.vpc[each.value.common.vpc].security_group_ids[v.security_group]], []) | ||
source_dest_check = try(v.source_dest_check, false) | ||
subnet_id = module.subnet_sets[v.vpc_subnet].subnets[each.value.az].id | ||
create_public_ip = try(v.create_public_ip, false) | ||
} | ||
} | ||
|
||
bootstrap_options = join(";", compact(concat(local.bootstrap_options[each.value.group], ["hostname=${var.name_prefix}${each.key}"]))) | ||
iam_instance_profile = aws_iam_instance_profile.vm_series_iam_instance_profile.name | ||
ssh_key_name = var.ssh_key_name | ||
tags = var.global_tags | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package vmseries_example_plan_and_deploy | ||
|
||
import ( | ||
"fmt" | ||
"math/rand" | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"github.com/PaloAltoNetworks/terraform-modules-vmseries-tests-skeleton/pkg/testskeleton" | ||
"github.com/gruntwork-io/terratest/modules/logger" | ||
"github.com/gruntwork-io/terratest/modules/terraform" | ||
) | ||
|
||
func TestVmseriesExamplePlanAndDeploy(t *testing.T) { | ||
// prepare random prefix | ||
source := rand.NewSource(time.Now().UnixNano()) | ||
random := rand.New(source) | ||
number := random.Intn(1000) | ||
namePrefix := fmt.Sprintf("terra%d-", number) | ||
|
||
// define options for Terraform | ||
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ | ||
TerraformDir: ".", | ||
VarFiles: []string{"example.tfvars"}, | ||
Vars: map[string]interface{}{ | ||
"name_prefix": namePrefix, | ||
"ssh_key_name": "test-ssh-key", | ||
}, | ||
Logger: logger.Default, | ||
Lock: true, | ||
Upgrade: true, | ||
SetVarsAfterVarFiles: true, | ||
}) | ||
|
||
// prepare list of items to check | ||
assertList := []testskeleton.AssertExpression{} | ||
|
||
// if DO_APPLY is not empty and equal true, then Terraform apply is used, in other case only Terraform plan | ||
if os.Getenv("DO_APPLY") == "true" { | ||
// deploy test infrastructure and verify outputs and check if there are no planned changes after deployment | ||
testskeleton.DeployInfraCheckOutputsVerifyChanges(t, terraformOptions, assertList) | ||
} else { | ||
// plan test infrastructure and verify outputs | ||
testskeleton.PlanInfraCheckErrors(t, terraformOptions, assertList, "No errors are expected") | ||
} | ||
} |
Oops, something went wrong.