diff --git a/README.md b/README.md
index 5a69601..c857070 100755
--- a/README.md
+++ b/README.md
@@ -26,17 +26,31 @@ This repository provides a structured set of Terraform modules for deploying Che
* [`gwlb`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/gwlb) - Deploys AWS Auto Scaling group configured for Gateway Load Balancer into an existing VPC.
* [`gwlb_master`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/gwlb_master) - Deploys AWS Auto Scaling group configured for Gateway Load Balancer into a new VPC.
* [`management`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/management) - Deploys CloudGuard Network Security Management Server into an existing VPC.
+* [`mds`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/mds) - Deploys CloudGuard Network Multi-Domain Server into an existing VPC.
+* [`qs_autoscale`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/qs_autoscale) - Deploys CloudGuard Network Security Gateway Auto Scaling Group, an external ALB/NLB, and optionally a Security Management Server and a web server Auto Scaling Group.
+* [`qs_autoscale_master`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/qs_autoscale_master) - Deploys CloudGuard Network Security Gateway Auto Scaling Group, an external ALB/NLB, and optionally a Security Management Server and a web server Auto Scaling Group in a new VPC.
+* [`standalone`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/standalone) - Check Point CloudGuard Network Security Gateway & Management (Standalone) instance into an existing VPC.
+* [`standalone_master`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/standalone_master) - CloudGuard Network Security Gateway & Management (Standalone) instance into a new VPC.
+* [`tgw_asg`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/tgw_asg) - Deploys CloudGuard Network Security Gateway Auto Scaling Group for Transit Gateway with an optional Management Server into an existing VPC.
+* [`tgw_asg_master`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/tgw_asg_master) - CloudGuard Network Security Gateway Auto Scaling Group for Transit Gateway with an optional Management Server in a new VPC.
+* [`tgw_cross_az_cluster`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/tgw_cross_az_cluster) - Deploys CloudGuard Network Security Cross AZ Cluster into an existing VPC on AWS for Transit Gateway.
+* [`tgw_cross_az_cluster_master`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/tgw_cross_az_cluster_master) - Deploys CloudGuard Network Security Cross AZ Cluster with a new VPC on AWS for Transit Gateway.
+* [`tgw_gwlb`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/tgw_gwlb) - Deploys WS Auto Scaling group configured for Gateway Load Balancer into existing Centralized Security VPC for Transit Gateway.
+* [`tgw_gwlb_master`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/tgw_gwlb_master) - Deploys AWS Auto Scaling group configured for Gateway Load Balancer into new Centralized Security VPC for Transit Gateway.
+
**Internal Submodules:**
* [`amis`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/amis)
* [`cloudwatch_policy`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/cloudwatch_policy)
-* [`elastic_ip`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/elastic_ip)
-* [`gateway_instance`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/gateway_instance)
-* [`instance_type`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/instance_type)
-* [`internal_default_route`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/internal_default_route)
-* [`load_balancer`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/load_balancer)
-* [`permissive_sg`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/permissive_sg)
-* [`version_license`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/common/version_license)
+* [`cluster_iam_role`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/cluster_iam_role)
+* [`custom_autoscale`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/custom_autoscale)
+* [`elastic_ip`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/elastic_ip)
+* [`gateway_instance`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/gateway_instance)
+* [`instance_type`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/instance_type)
+* [`internal_default_route`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/internal_default_route)
+* [`load_balancer`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/load_balancer)
+* [`permissive_sg`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/permissive_sg)
+* [`version_license`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/version_license)
* [`vpc`](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest/submodules/vpc)
***
diff --git a/examples/qs_autoscale/README.md b/examples/qs_autoscale/README.md
new file mode 100755
index 0000000..3fc9a44
--- /dev/null
+++ b/examples/qs_autoscale/README.md
@@ -0,0 +1,169 @@
+# Check Point CloudGuard Network Quick Start Auto Scaling Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Gateway Auto Scaling Group, an external ALB/NLB, and optionally a Security Management Server and a web server Auto Scaling Group.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Load Balancer](https://www.terraform.io/docs/providers/aws/r/lb.html)
+* [Load Balancer Target Group](https://www.terraform.io/docs/providers/aws/r/lb_target_group.html)
+* [Launch template](https://www.terraform.io/docs/providers/aws/r/launch_template.html)
+* [Auto Scaling Group](https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Check Point CloudGuard Auto Scaling on AWS](https://aws.amazon.com/quickstart/architecture/check-point-cloudguard/) for additional information
+
+This solution uses the following modules:
+- autoscale
+- custom_autoscale
+- management
+- cme_iam_role
+
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//examples/qs_autoscale"
+ version = "1.0.0"
+
+ //PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW
+
+ // --- Environment ---
+ prefix = "TF"
+ asg_name = "asg-qs"
+
+ // --- General Settings ---
+ vpc_id = "vpc-12345678"
+ key_name = "publickey"
+ enable_volume_encryption = true
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+ provision_tag = "quickstart"
+ load_balancers_type = "Application Load Balancer"
+ load_balancer_protocol = "HTTP"
+ certificate = ""
+ service_port = "80"
+ admin_shell = "/etc/cli.sh"
+
+ // --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+ gateways_subnets = ["subnet-123b5678", "subnet-123a4567"]
+ gateway_instance_type = "c5.xlarge"
+ gateways_min_group_size = 2
+ gateways_max_group_size = 8
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ enable_cloudwatch = true
+
+ // --- Check Point CloudGuard Network Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 the management_password_hash is used also as maintenance-mode password.
+ gateways_policy = "Standard"
+ gateways_blades = true
+ admin_cidr = "0.0.0.0/0"
+ gateways_addresses = "0.0.0.0/0"
+
+ // --- Web Servers Auto Scaling Group Configuration ---
+ servers_deploy = false
+ servers_subnets = ["subnet-1234abcd", "subnet-56789def"]
+ servers_instance_type = "t3.micro"
+ server_ami = "ami-12345678"
+ }
+ ```
+
+- Conditional creation
+ - To enable cloudwatch for ASG:
+ ```
+ enable_cloudwatch = true
+ ```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To deploy Security Management Server:
+ ```
+ management_deploy = true
+ ```
+ - To deploy web servers:
+ ```
+ servers_deploy = true
+ ```
+ - To create an ASG configuration without a proxy ELB:
+ ```
+ proxy_elb_type= "none"
+ ```
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------|
+| prefix | (Optional) Instances name prefix | string | |
+| asg_name | Autoscaling Group name | string | |
+| vpc_id | Select an existing VPC | string | |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents an instance from accidental termination. Note: Once this attribute is true terraform destroy won't work properly | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false
**Default:** true |
+| provision_tag | The tag used by the Security Management Server to automatically provision the Security Gateways | string |
**Default:** quickstart |
+| load_balancers_type | Use Network Load Balancer if you wish to preserve the source IP address or Application Load Balancer for content-based routing | string | - Network Load Balancer
- Application Load Balancer
**Default:** Network Load Balancer |
+| load_balancer_protocol | The protocol to use on the Load Balancer | string | Network Load Balancer: TCP, TLS, UDP, TCP_UDP
Application Load Balancer: HTTP, HTTPS
**Default:** TCP |
+| certificate | Amazon Resource Name (ARN) of an HTTPS Certificate, ignored if the selected protocol is HTTP | string | |
+| service_port | The external Load Balancer listens to this port. Leave blank for default: 80 (HTTP) or 443 (HTTPS) | string | |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| gateways_subnets | Select at least 2 public subnets in the VPC. If deploying a Security Management Server, it will be in the first subnet | list(string) | |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| gateways_min_group_size | The minimal number of Security Gateways | number |
**Default:** 2 |
+| gateways_max_group_size | The maximal number of Security Gateways | number |
**Default:** 10 |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| gateway_password_hash | (Optional) Admin user's password hash (use `openssl passwd -6 PASSWORD` to get the hash) | string | |
+| gateway_SIC_Key | Secure Internal Communication key for trusted connection between Check Point components | string |
**Default:** 12345678 |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| management_deploy | Select 'false' to use an existing Security Management Server or deploy one later | bool | true/false
**Default:** true |
+| management_instance_type | The EC2 instance type of the Security Management Server | string | - c5.large
- c5.xlarge
- m6a.large
**Default:** m5.xlarge |
+| management_version | The license to install on the Security Management Server | string | - R81.10-BYOL
- R81.20-BYOL
**Default:** R81.20-BYOL |
+| gateways_policy | The name of the Security Policy package for gateways in the Auto Scaling group | string |
**Default:** Standard |
+| gateways_blades | Turn on the Intrusion Prevention System, Application Control, Anti-Virus, and Anti-Bot Blades | bool | true/false
**Default:** true |
+| admin_cidr | (CIDR) Allow web, SSH, and graphical clients only from this network to communicate with the Management Server | string | valid CIDR |
+| gateway_addresses | (CIDR) Allow gateways only from this network to communicate with the Management Server | string | valid CIDR |
+| servers_deploy | Select 'true' to deploy web servers and an internal Application Load Balancer. 'False' ignores related parameters | bool | true/false
**Default:** false |
+| servers_subnets | Provide at least 2 private subnet IDs in the chosen VPC | list(string) | |
+| servers_instance_type | The EC2 instance type for the web servers | string | - t3.nano
- t3.micro
- t3.small
- t3.medium
- t3.large
- t3.xlarge
- t3.2xlarge**Default:** t3.micro |
+| server_ami | Amazon Machine Image ID of a preconfigured web server | string | |
+| gateway_maintenance_mode_password_hash | Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+
+| Name | Description |
+|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| management_name | The deployed Security Management AWS instance name |
+| internal_port | The internal Load Balancer should listen to this port |
+| load_balancer_url | The URL of the external Load Balancer |
+| external_load_balancer_arn | The external Load Balancer ARN |
+| internal_load_balancer_arn | The internal Load Balancer ARN |
+| external_LB_target_group_arn | The external Load Balancer Target Group ARN |
+| internal_LB_target_group_arn | The internal Load Balancer Target Group ARN |
+| autoscale_autoscaling_group_name | The name of the deployed AutoScaling Group |
+| autoscale_autoscaling_group_arn | The ARN for the deployed AutoScaling Group |
+| autoscale_security_group_id | The deployed AutoScaling Group's security group id |
+| autoscale_iam_role_name | The deployed AutoScaling Group's IAM role name (if created) |
+| configuration_template | The name that represents the configuration template. Configurations required to automatically provision the Gateways in the Auto Scaling Group, such as what Security Policy to install and which Blades to enable, will be placed under this template name |
+| controller_name | The name that represents the controller. Configurations required to connect to your AWS environment, such as credentials and regions, will be placed under this controller name |
diff --git a/examples/qs_autoscale/locals.tf b/examples/qs_autoscale/locals.tf
new file mode 100755
index 0000000..2ecac5d
--- /dev/null
+++ b/examples/qs_autoscale/locals.tf
@@ -0,0 +1,71 @@
+locals {
+ load_balancer_name = format("%sLB", var.prefix != "" ? format("%s-", var.prefix) : "")
+ target_group_name = format("%sTG", var.prefix != "" ? format("%s-", var.prefix) : "")
+ regex_valid_provision_tag = "^[a-zA-Z0-9-]{1,12}$"
+ // Will fail if var.provision_tag is invalid
+ regex_provision_tag = regex(local.regex_valid_provision_tag, var.provision_tag) == var.provision_tag ? 0 : "Variable [provision_tag] must be up to 12 alphanumeric characters and unique for each Quick Start deployment"
+
+ load_balancers_type_allowed_values = [
+ "Network Load Balancer",
+ "Application Load Balancer"
+ ]
+ // Will fail if var.load_balancers_type is invalid
+ validate_load_balancers_type = index(local.load_balancers_type_allowed_values, var.load_balancers_type)
+
+ lb_protocol_allowed_values = var.load_balancers_type == "Network Load Balancer" ? [
+ "TCP",
+ "TLS",
+ "UDP",
+ "TCP_UDP"
+ ] : [
+ "HTTP",
+ "HTTPS"
+ ]
+ // Will fail if var.load_balancer_protocol is invalid
+ validate_lb_protocol = index(local.lb_protocol_allowed_values, var.load_balancer_protocol)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_certificate = "^(arn:aws:[a-z]+::[0-9]{12}:server-certificate/[a-zA-Z0-9-]*)?$"
+ // Will fail if var.certificate is invalid
+ regex_certificate = regex(local.regex_valid_certificate, var.certificate) == var.certificate ? 0 : "Variable [certificate] must be a valid Amazon Resource Name (ARN), for example: arn:aws:iam::123456789012:server-certificate/web-server-certificate"
+
+ regex_valid_service_port = "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?$"
+ // Will fail if var.service_port is invalid
+ regex_service_port = regex(local.regex_valid_service_port, var.service_port) == var.service_port ? 0 : "Custom service port must be a number between 0 and 65535"
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash."
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters."
+
+ regex_valid_management_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_management_password_hash = regex(local.regex_valid_management_password_hash, var.management_password_hash) == var.management_password_hash ? 0 : "Variable [management_password_hash] must be a valid password hash."
+ regex_management_maintenance_mode_password_hash = regex(local.regex_valid_management_password_hash, var.management_maintenance_mode_password_hash) == var.management_maintenance_mode_password_hash ? 0 : "Variable [management_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_admin_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.admin_cidr is invalid
+ regex_admin_cidr = regex(local.regex_valid_admin_cidr, var.admin_cidr) == var.admin_cidr ? 0 : "Variable [admin_cidr] must be a valid CIDR."
+
+ regex_valid_gateways_addresses = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.gateways_addresses is invalid
+ regex_gateways_addresses = regex(local.regex_valid_gateways_addresses, var.gateways_addresses) == var.gateways_addresses ? 0 : "Variable [gateways_addresses] must be a valid gateways addresses."
+
+ regex_valid_server_ami = "^(ami-(([0-9a-f]{8})|([0-9a-f]{17})))?$"
+ // Will fail if var.server_ami is invalid
+ regex_server_ami = regex(local.regex_valid_server_ami, var.server_ami) == var.server_ami ? 0 : "Amazon Machine Image ID must be in the form ami-xxxxxxxx or ami-xxxxxxxxxxxxxxxxx"
+
+ alb_condition = var.load_balancers_type == "Application Load Balancer"
+ nlb_condition = var.load_balancers_type == "Network Load Balancer"
+ provided_port_condition = var.service_port != ""
+ encrypted_protocol_condition = (local.alb_condition && var.load_balancer_protocol == "HTTPS") || (local.nlb_condition && var.load_balancer_protocol == "TLS") ? true : false
+ deploy_management_condition = var.management_deploy == true
+ deploy_servers_condition = var.servers_deploy == true
+}
\ No newline at end of file
diff --git a/examples/qs_autoscale/main.tf b/examples/qs_autoscale/main.tf
new file mode 100755
index 0000000..8c85aab
--- /dev/null
+++ b/examples/qs_autoscale/main.tf
@@ -0,0 +1,175 @@
+resource "aws_security_group" "external_alb_security_group" {
+ count = local.alb_condition ? 1 : 0
+ description = "External ALB security group"
+ vpc_id = var.vpc_id
+
+ egress {
+ from_port = local.encrypted_protocol_condition ? 9443 : 9080
+ protocol = "tcp"
+ to_port = local.encrypted_protocol_condition ? 9443 : 9080
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ ingress {
+ from_port = local.provided_port_condition ? var.service_port : local.encrypted_protocol_condition ? 443 : 80
+ protocol = "tcp"
+ to_port = local.provided_port_condition ? var.service_port : local.encrypted_protocol_condition ? 443 : 80
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ dynamic "ingress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "ingress"]
+ content {
+ from_port = ingress.value.from_port
+ to_port = ingress.value.to_port
+ protocol = ingress.value.protocol
+ cidr_blocks = ingress.value.cidr_blocks
+ }
+ }
+
+ dynamic "egress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "egress"]
+ content {
+ from_port = egress.value.from_port
+ to_port = egress.value.to_port
+ protocol = egress.value.protocol
+ cidr_blocks = egress.value.cidr_blocks
+ }
+ }
+}
+
+module "external_load_balancer" {
+ source = "../../modules/load_balancer"
+
+ load_balancers_type = var.load_balancers_type
+ instances_subnets = var.gateways_subnets
+ prefix_name = "${var.prefix}-External"
+ internal = false
+ security_groups = local.alb_condition ? [aws_security_group.external_alb_security_group[0].id] : []
+ tags = {}
+ vpc_id = var.vpc_id
+ load_balancer_protocol = var.load_balancer_protocol
+ target_group_port = local.encrypted_protocol_condition ? 9443 : 9080
+ listener_port = local.provided_port_condition ? var.service_port : local.encrypted_protocol_condition ? "443" : "80"
+ certificate_arn = local.encrypted_protocol_condition ? var.certificate : ""
+ health_check_port = var.load_balancers_type == "Network Load Balancer" ? 8117 : null
+ health_check_protocol = var.load_balancers_type == "Network Load Balancer" ? "TCP" : null
+}
+
+module "autoscale" {
+ source = "../../modules/autoscale"
+
+
+ prefix = var.prefix
+ asg_name = var.asg_name
+ vpc_id = var.vpc_id
+ subnet_ids = var.gateways_subnets
+ gateway_name = "${var.provision_tag}-security-gateway"
+ gateway_instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ enable_volume_encryption = var.enable_volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ minimum_group_size = var.gateways_min_group_size
+ maximum_group_size = var.gateways_max_group_size
+ target_groups = tolist([module.external_load_balancer.target_group_arn])
+ gateway_version = var.gateway_version
+ admin_shell = var.admin_shell
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ gateway_SICKey = var.gateway_SICKey
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = "echo -e '\nStarting Bootstrap script\n'; echo 'Adding quickstart identifier to cloud-version'; cv_path='/etc/cloud-version'\n if test -f \"$cv_path\"; then sed -i '/template_name/c\\template_name: autoscale_qs' /etc/cloud-version; fi; cv_json_path='/etc/cloud-version.json'\n cv_json_path_tmp='/etc/cloud-version-tmp.json'\n if test -f \"$cv_json_path\"; then cat \"$cv_json_path\" | jq '.template_name = \"'\"autoscale_qs\"'\"' > \"$cv_json_path_tmp\"; mv \"$cv_json_path_tmp\" \"$cv_json_path\"; fi; echo -e '\nFinished Bootstrap script\n'"
+ management_server = "${var.provision_tag}-management"
+ configuration_template = "${var.provision_tag}-template"
+}
+
+data "aws_region" "current"{}
+
+module "management" {
+
+ count = local.deploy_management_condition ? 1 : 0
+ source = "../../modules/management"
+
+ vpc_id = var.vpc_id
+ subnet_id = var.gateways_subnets[0]
+ management_name = "${var.provision_tag}-management"
+ management_instance_type = var.management_instance_type
+ key_name = var.key_name
+ volume_encryption = var.enable_volume_encryption ? "alias/aws/ebs" : ""
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ iam_permissions = "Create with read-write permissions"
+ management_version = var.management_version
+ admin_shell = var.admin_shell
+ management_password_hash = var.management_password_hash
+ management_maintenance_mode_password_hash = var.management_maintenance_mode_password_hash
+ allow_upload_download = var.allow_upload_download
+ admin_cidr = var.admin_cidr
+ gateway_addresses = var.gateways_addresses
+ management_bootstrap_script = "echo -e '\nStarting Bootstrap script\n'; echo 'Adding quickstart identifier to cloud-version'; cv_path='/etc/cloud-version'\n if test -f \"$cv_path\"; then sed -i '/template_name/c\\template_name: management_qs' /etc/cloud-version; fi; cv_json_path='/etc/cloud-version.json'\n cv_json_path_tmp='/etc/cloud-version-tmp.json'\n if test -f \"$cv_json_path\"; then cat \"$cv_json_path\" | jq '.template_name = \"'\"management_qs\"'\"' > \"$cv_json_path_tmp\"; mv \"$cv_json_path_tmp\" \"$cv_json_path\"; fi; echo 'Creating CME configuration'; autoprov_cfg -f init AWS -mn ${var.provision_tag}-management -tn ${var.provision_tag}-template -cn ${var.provision_tag}-controller -po ${var.gateways_policy} -otp ${var.gateway_SICKey} -r ${data.aws_region.current.name} -ver ${split("-", var.gateway_version)[0]} -iam; ${var.gateways_blades} && autoprov_cfg -f set template -tn ${var.provision_tag}-template -ips -appi -av -ab; echo -e '\nFinished Bootstrap script\n'"
+}
+
+resource "aws_security_group" "internal_security_group" {
+ count = local.deploy_servers_condition ? 1 : 0
+ vpc_id = var.vpc_id
+
+ egress {
+ from_port = local.provided_port_condition ? var.service_port : local.encrypted_protocol_condition ? 443 : 80
+ protocol = "tcp"
+ to_port = local.provided_port_condition ? var.service_port : local.encrypted_protocol_condition ? 443 : 80
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ ingress {
+ from_port = local.encrypted_protocol_condition ? 443 : 80
+ protocol = "tcp"
+ to_port = local.encrypted_protocol_condition ? 443 : 80
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ ingress {
+ from_port = -1
+ protocol = "icmp"
+ to_port = -1
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+}
+
+module "internal_load_balancer" {
+ count = local.deploy_servers_condition ? 1 : 0
+ source = "../../modules/load_balancer"
+
+ load_balancers_type = var.load_balancers_type
+ instances_subnets = var.servers_subnets
+ prefix_name = "${var.prefix}-Internal"
+ internal = true
+ security_groups = local.alb_condition ? [aws_security_group.internal_security_group[0].id] : []
+ tags = {
+ x-chkp-management = "${var.provision_tag}-management"
+ x-chkp-template = "${var.provision_tag}-template"
+ }
+ vpc_id = var.vpc_id
+ load_balancer_protocol = var.load_balancer_protocol
+ target_group_port = local.encrypted_protocol_condition ? 443 : 80
+ listener_port = local.encrypted_protocol_condition ? "443" : "80"
+ certificate_arn = local.encrypted_protocol_condition ? var.certificate : ""
+}
+
+module "custom_autoscale" {
+ count = local.deploy_servers_condition ? 1 : 0
+ source = "../../modules/custom_autoscale"
+
+ prefix = var.prefix
+ asg_name = var.asg_name
+ vpc_id = var.vpc_id
+ servers_subnets = var.servers_subnets
+ server_ami = var.server_ami
+ server_name = "${var.provision_tag}-server"
+ servers_instance_type = var.servers_instance_type
+ key_name = var.key_name
+ servers_min_group_size = var.gateways_min_group_size
+ servers_max_group_size = var.gateways_max_group_size
+ servers_target_groups = module.internal_load_balancer[0].target_group_id
+ deploy_internal_security_group = local.nlb_condition ? true : false
+ source_security_group = local.nlb_condition ? "" : aws_security_group.internal_security_group[0].id
+}
\ No newline at end of file
diff --git a/examples/qs_autoscale/output.tf b/examples/qs_autoscale/output.tf
new file mode 100755
index 0000000..edb1a1f
--- /dev/null
+++ b/examples/qs_autoscale/output.tf
@@ -0,0 +1,45 @@
+output "Deployment" {
+ value = "Finalizing instances configuration may take up to 20 minutes after deployment is finished."
+}
+
+output "management_name" {
+ value = "${var.provision_tag}-management"
+}
+output "internal_port" {
+ value = local.encrypted_protocol_condition ? 443 : 80
+}
+output "load_balancer_url" {
+ value = module.external_load_balancer.load_balancer_url
+}
+output "external_load_balancer_arn" {
+ value = module.external_load_balancer.load_balancer_arn
+}
+output "internal_load_balancer_arn" {
+ value = module.internal_load_balancer[*].load_balancer_arn
+}
+output "external_lb_target_group_arn" {
+ value = module.external_load_balancer.target_group_arn
+}
+output "internal_lb_target_group_arn" {
+ value = module.internal_load_balancer[*].target_group_arn
+}
+
+output "autoscale_autoscaling_group_name" {
+ value = module.autoscale.autoscale_autoscaling_group_name
+}
+output "autoscale_autoscaling_group_arn" {
+ value = module.autoscale.autoscale_autoscaling_group_arn
+}
+output "autoscale_security_group_id" {
+ value = module.autoscale.autoscale_security_group_id
+}
+output "autoscale_iam_role_name" {
+ value = module.autoscale.autoscale_iam_role_name
+}
+
+output "configuration_template" {
+ value = "${var.provision_tag}-template"
+}
+output "controller_name" {
+ value = "${var.provision_tag}-controller"
+}
diff --git a/examples/qs_autoscale/variables.tf b/examples/qs_autoscale/variables.tf
new file mode 100755
index 0000000..a3d4012
--- /dev/null
+++ b/examples/qs_autoscale/variables.tf
@@ -0,0 +1,233 @@
+// Module: Check Point CloudGuard Network Quick Start Auto Scaling
+//Deploy a Check Point CloudGuard Network Security Gateways Auto Scaling Group, an external ALB/NLB, and optionally a Security Management Server and a web server Auto Scaling Group.
+
+// --- Environment ---
+variable "prefix" {
+ type = string
+ description = "(Optional) Instances name prefix"
+ default = ""
+ validation {
+ condition = length(var.prefix) <= 40
+ error_message = "Prefix can not exceed 40 characters."
+ }
+}
+variable "asg_name" {
+ type = string
+ description = "Autoscaling Group name"
+ default = "Check-Point-ASG-tf"
+ validation {
+ condition = length(var.asg_name) <= 100
+ error_message = "Autoscaling Group name can not exceed 100 characters."
+ }
+}
+// --- General Settings ---
+variable "vpc_id" {
+ type = string
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "provision_tag" {
+ type = string
+ description = "The tag is used by the Security Management Server to automatically provision the Security Gateways. Must be up to 12 alphanumeric characters and unique for each Quick Start deployment"
+ default = "quickstart"
+}
+variable "load_balancers_type" {
+ type = string
+ description = "Use Network Load Balancer if you wish to preserve the source IP address and Application Load Balancer if you wish to use content based routing"
+ default = "Network Load Balancer"
+}
+variable "load_balancer_protocol" {
+ type = string
+ description = "The protocol to use on the Load Balancer"
+}
+variable "certificate" {
+ type = string
+ description = "Amazon Resource Name (ARN) of an HTTPS Certificate, ignored if the selected protocol is HTTP"
+}
+variable "service_port" {
+ type = string
+ description = "The external Load Balancer listens to this port. Leave this field blank to use default ports: 80 for HTTP and 443 for HTTPS"
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+
+// --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+variable "gateways_subnets" {
+ type = list(string)
+ description = "Select at least 2 public subnets in the VPC. If you choose to deploy a Security Management Server it will be deployed in the first subnet"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_gateway_instance_type" {
+ source = "../../modules/instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "gateways_min_group_size" {
+ type = number
+ description = "The minimal number of Security Gateways"
+ default = 2
+}
+variable "gateways_max_group_size" {
+ type = number
+ description = "The maximal number of Security Gateways"
+ default = 10
+}
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../../modules/version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+
+// --- Check Point CloudGuard Network Security Management Server Configuration ---
+variable "management_deploy" {
+ type = bool
+ description = "Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section"
+ default = true
+}
+variable "management_instance_type" {
+ type = string
+ description = "The EC2 instance type of the Security Management Server"
+ default = "m5.xlarge"
+}
+module "validate_management_instance_type" {
+ source = "../../modules/instance_type"
+
+ chkp_type = "management"
+ instance_type = var.management_instance_type
+}
+variable "management_version" {
+ type = string
+ description = "The license to install on the Security Management Server"
+ default = "R81.20-BYOL"
+}
+module "validate_management_version" {
+ source = "../../modules/version_license"
+
+ chkp_type = "management"
+ version_license = var.management_version
+}
+variable "management_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "management_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "gateways_policy" {
+ type = string
+ description = "The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group"
+ default = "Standard"
+}
+variable "gateways_blades" {
+ type = bool
+ description = "Turn on the Intrusion Prevention System, Application Control, Anti-Virus and Anti-Bot Blades (additional Blades can be manually turned on later)"
+ default = true
+}
+variable "admin_cidr" {
+ type = string
+ description = "Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server"
+}
+variable "gateways_addresses" {
+ type = string
+ description = "Allow gateways only from this network to communicate with the Security Management Server"
+}
+
+// --- Web Servers Auto Scaling Group Configuration ---
+variable "servers_deploy" {
+ type = bool
+ description = "Select 'true' to deploy web servers and an internal Application Load Balancer. If you select 'false' the other parameters of this section will be ignored"
+ default = false
+}
+variable "servers_subnets" {
+ type = list(string)
+ description = "Provide at least 2 private subnet IDs in the chosen VPC, separated by commas (e.g. subnet-1234,subnet-5678,subnet-9012)"
+}
+variable "servers_instance_type" {
+ type = string
+ description = "The EC2 instance type for the web servers"
+ default = "t3.micro"
+}
+module "validate_servers_instance_type" {
+ source = "../../modules/instance_type"
+
+ chkp_type = "server"
+ instance_type = var.servers_instance_type
+}
+variable "server_ami" {
+ type = string
+ description = "The Amazon Machine Image ID of a preconfigured web server (e.g. ami-1234)"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
diff --git a/examples/qs_autoscale/versions.tf b/examples/qs_autoscale/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/examples/qs_autoscale/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/examples/qs_autoscale_master/README.md b/examples/qs_autoscale_master/README.md
new file mode 100755
index 0000000..9630c9f
--- /dev/null
+++ b/examples/qs_autoscale_master/README.md
@@ -0,0 +1,177 @@
+# Check Point CloudGuard Network Quick Start Auto Scaling Master Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Gateway Auto Scaling Group, an external ALB/NLB, and optionally a Security Management Server and a web server Auto Scaling Group in a new VPC.
+
+These types of Terraform resources are supported:
+* [VPC](https://www.terraform.io/docs/providers/aws/r/vpc.html)
+* [Subnet](https://www.terraform.io/docs/providers/aws/r/subnet.html)
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Load Balancer](https://www.terraform.io/docs/providers/aws/r/lb.html)
+* [Load Balancer Target Group](https://www.terraform.io/docs/providers/aws/r/lb_target_group.html)
+* [Launch template](https://www.terraform.io/docs/providers/aws/r/launch_template.html)
+* [Auto Scaling Group](https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html)
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Check Point CloudGuard Auto Scaling on AWS](https://aws.amazon.com/quickstart/architecture/check-point-cloudguard/) for additional information
+
+This solution uses the following modules:
+- qs_autoscale
+- autoscale
+- management
+- cme_iam_role
+- vpc
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//examples/qs_autoscale_master"
+ version = "1.0.0"
+
+
+ // --- Environment ---
+ prefix = "TF"
+ asg_name = "asg-qs"
+
+ // --- Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ "us-east-1b" = 2
+ }
+ private_subnets_map = {
+ "us-east-1a" = 3
+ "us-east-1b" = 4
+ }
+ subnets_bit_length = 8
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+ provision_tag = "quickstart"
+ load_balancers_type = "Network Load Balancer"
+ load_balancer_protocol = "TCP"
+ certificate = "arn:aws:iam::12345678:server-certificate/certificate"
+ service_port = "80"
+ admin_shell = "/etc/cli.sh"
+
+ // --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+ gateway_instance_type = "c5.xlarge"
+ gateways_min_group_size = 2
+ gateways_max_group_size = 8
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ enable_cloudwatch = false
+
+ // --- Check Point CloudGuard Network Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 the management_password_hash is used also as maintenance-mode password.
+ gateways_policy = "Standard"
+ gateways_blades = true
+ admin_cidr = "0.0.0.0/0"
+ gateways_addresses = "0.0.0.0/0"
+
+ // --- Web Servers Auto Scaling Group Configuration ---
+ servers_deploy = true
+ servers_instance_type = "t3.micro"
+ server_ami = "ami-12345abc"
+ }
+```
+
+- Conditional creation
+ - To enable cloudwatch for ASG:
+ ```
+ enable_cloudwatch = true
+ ```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To deploy Security Management Server:
+ ```
+ management_deploy = true
+ ```
+ - To deploy web servers:
+ ```
+ servers_deploy = true
+ ```
+ - To create an ASG configuration without a proxy ELB:
+ ```
+ proxy_elb_type= "none"
+ ```
+
+
+## Inputs
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------|
+| prefix | (Optional) Instances name prefix | string | |
+| asg_name | Autoscaling Group name | string | |
+| vpc_cidr | The CIDR block of the VPC | string | |
+| public_subnets_map | Map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs (e.g., {"us-east-1a" = 1}) | map | |
+| private_subnets_map | Map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs (e.g., {"us-east-1a" = 2}) | map | |
+| subnets_bit_length | Number of additional bits to extend the VPC CIDR. For example, if given a VPC CIDR ending in /16 and a value of 4, resulting subnet length will be /20 | number | |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents accidental instance termination. Note: Once true, terraform destroy won't work properly | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set to true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| allow_upload_download | Automatically download Blade Contracts and other important data to improve the product experience | bool | true/false
**Default:** true |
+| provision_tag | Tag used by the Security Management Server to provision Security Gateways automatically | string |
**Default:** quickstart |
+| load_balancers_type | Use Network Load Balancer to preserve source IP address or Application Load Balancer for content-based routing | string | - Network Load Balancer
- Application Load Balancer
**Default:** Network Load Balancer |
+| load_balancer_protocol | Protocol to use on the Load Balancer | string | - TCP
- TLS
- UDP
- TCP_UDP
- HTTP (Application Load Balancer)
- HTTPS (Application Load Balancer)
**Default:** TCP |
+| certificate | Amazon Resource Name (ARN) of an HTTPS Certificate. Ignored if the selected protocol is HTTP | string | |
+| service_port | Port the Load Balancer listens to externally. Leave blank for defaults: 80 for HTTP, 443 for HTTPS | string | |
+| admin_shell | Admin shell configuration for advanced command-line access | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh
**Default:** /etc/cli.sh |
+| gateways_subnets | At least 2 public subnets in the VPC. Security Management Server (if deployed) will reside in the first subnet | list(string) | |
+| gateway_instance_type | Instance type for the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| gateways_min_group_size | Minimum number of Security Gateways | number |
**Default:** 2 |
+| gateways_max_group_size | Maximum number of Security Gateways | number |
**Default:** 10 |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| gateway_SIC_Key | Secure Internal Communication key for trusted connection between Check Point components | string |
**Default:** 12345678 |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| servers_deploy | Deploy web servers and an internal Application Load Balancer. 'False' ignores related parameters | bool | true/false
**Default:** false |
+| servers_instance_type | EC2 instance type for web servers | string | - t3.nano
- t3.micro
- t3.small
- t3.medium
- t3.large
- t3.xlarge
- t3.2xlarge**Default:** t3.micro |
+| server_ami | Amazon Machine Image ID of a preconfigured web server (e.g., ami-0dc7dc63) | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| vpc_id | The id of the deployed vpc |
+| public_subnets_ids_list | A list of the public subnets ids |
+| private_subnets_ids_list | A list of the private subnets ids |
+| public_rout_table | The public route table id |
+| internal_port | The internal Load Balancer should listen to this port |
+| management_name | The deployed Security Management AWS instance name |
+| load_balancer_url | The URL of the external Load Balancer |
+| external_load_balancer_arn | The external Load Balancer ARN |
+| internal_load_balancer_arn | The internal Load Balancer ARN |
+| external_lb_target_group_arn | The external Load Balancer Target Group ARN |
+| internal_lb_target_group_arn | The internal Load Balancer Target Group ARN |
+| autoscale_autoscaling_group_name | The name of the deployed AutoScaling Group |
+| autoscale_autoscaling_group_arn | The ARN for the deployed AutoScaling Group |
+| autoscale_security_group_id | The deployed AutoScaling Group's security group id |
+| autoscale_iam_role_name | The deployed AutoScaling Group's IAM role name (if created) |
+| configuration_template | The name that represents the configuration template. Configurations required to automatically provision the Gateways in the Auto Scaling Group, such as what Security Policy to install and which Blades to enable, will be placed under this template name |
+| controller_name | The name that represents the controller. Configurations required to connect to your AWS environment, such as credentials and regions, will be placed under this controller name |
diff --git a/examples/qs_autoscale_master/locals.tf b/examples/qs_autoscale_master/locals.tf
new file mode 100755
index 0000000..e23f58a
--- /dev/null
+++ b/examples/qs_autoscale_master/locals.tf
@@ -0,0 +1,63 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ regex_valid_provision_tag = "^[a-zA-Z0-9-]{1,12}$"
+ // Will fail if var.provision_tag is invalid
+ regex_provision_tag = regex(local.regex_valid_provision_tag, var.provision_tag) == var.provision_tag ? 0 : "Variable [provision_tag] must be up to 12 alphanumeric characters and unique for each Quick Start deployment"
+
+ load_balancers_type_allowed_values = [
+ "Network Load Balancer",
+ "Application Load Balancer"]
+ // Will fail if var.load_balancers_type is invalid
+ validate_load_balancers_type = index(local.load_balancers_type_allowed_values, var.load_balancers_type)
+
+ lb_protocol_allowed_values = var.load_balancers_type == "Network Load Balancer" ? [
+ "TCP",
+ "TLS",
+ "UDP",
+ "TCP_UDP"] : [
+ "HTTP",
+ "HTTPS"]
+ // Will fail if var.load_balancer_protocol is invalid
+ validate_lb_protocol = index(local.lb_protocol_allowed_values, var.load_balancer_protocol)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_certificate = "^(arn:aws:[a-z]+::[0-9]{12}:server-certificate/[a-zA-Z0-9-]*)?$"
+ // Will fail if var.certificate is invalid
+ regex_certificate = regex(local.regex_valid_certificate, var.certificate) == var.certificate ? 0 : "Variable [certificate] must be a valid Amazon Resource Name (ARN), for example: arn:aws:iam::123456789012:server-certificate/web-server-certificate"
+
+ regex_valid_service_port = "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?$"
+ // Will fail if var.service_port is invalid
+ regex_service_port = regex(local.regex_valid_service_port, var.service_port) == var.service_port ? 0 : "Custom service port must be a number between 0 and 65535"
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash."
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters."
+
+ regex_valid_management_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_management_password_hash = regex(local.regex_valid_management_password_hash, var.management_password_hash) == var.management_password_hash ? 0 : "Variable [management_password_hash] must be a valid password hash."
+
+ regex_valid_admin_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.admin_cidr is invalid
+ regex_admin_cidr = regex(local.regex_valid_admin_cidr, var.admin_cidr) == var.admin_cidr ? 0 : "Variable [admin_cidr] must be a valid CIDR."
+
+ regex_valid_gateways_addresses = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.gateways_addresses is invalid
+ regex_gateways_addresses = regex(local.regex_valid_gateways_addresses, var.gateways_addresses) == var.gateways_addresses ? 0 : "Variable [gateways_addresses] must be a valid gateways addresses."
+
+
+ regex_valid_server_ami = "^(ami-(([0-9a-f]{8})|([0-9a-f]{17})))?$"
+ // Will fail if var.server_ami is invalid
+ regex_server_ami = regex(local.regex_valid_server_ami, var.server_ami) == var.server_ami ? 0 : "Amazon Machine Image ID must be in the form ami-xxxxxxxx or ami-xxxxxxxxxxxxxxxxx"
+}
\ No newline at end of file
diff --git a/examples/qs_autoscale_master/main.tf b/examples/qs_autoscale_master/main.tf
new file mode 100755
index 0000000..cfb7d19
--- /dev/null
+++ b/examples/qs_autoscale_master/main.tf
@@ -0,0 +1,53 @@
+module "launch_vpc" {
+ source = "../../modules/vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = var.private_subnets_map
+ subnets_bit_length = var.subnets_bit_length
+}
+
+module "launch_qs_autoscale" {
+ source = "../qs_autoscale"
+
+
+
+ prefix = var.prefix
+ asg_name = var.asg_name
+ vpc_id = module.launch_vpc.vpc_id
+ security_rules = var.security_rules
+ key_name = var.key_name
+ enable_volume_encryption = var.enable_volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ allow_upload_download = var.allow_upload_download
+ provision_tag = var.provision_tag
+ load_balancers_type = var.load_balancers_type
+ load_balancer_protocol = var.load_balancer_protocol
+ certificate = var.certificate
+ service_port = var.service_port
+ admin_shell = var.admin_shell
+ gateways_subnets = module.launch_vpc.public_subnets_ids_list
+ gateway_instance_type = var.gateway_instance_type
+ gateways_min_group_size = var.gateways_min_group_size
+ gateways_max_group_size = var.gateways_max_group_size
+ gateway_version = var.gateway_version
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ gateway_SICKey = var.gateway_SICKey
+ enable_cloudwatch = var.enable_cloudwatch
+ management_deploy = var.management_deploy
+ management_instance_type = var.management_instance_type
+ management_version = var.management_version
+ management_password_hash = var.gateway_password_hash
+ management_maintenance_mode_password_hash = var.management_maintenance_mode_password_hash
+ gateways_policy = var.gateways_policy
+ gateways_blades = var.gateways_blades
+ admin_cidr = var.admin_cidr
+ gateways_addresses = var.gateways_addresses
+ servers_deploy= var.servers_deploy
+ servers_subnets = module.launch_vpc.private_subnets_ids_list
+ servers_instance_type = var.servers_instance_type
+ server_ami = var.server_ami
+}
\ No newline at end of file
diff --git a/examples/qs_autoscale_master/output.tf b/examples/qs_autoscale_master/output.tf
new file mode 100755
index 0000000..1130dfe
--- /dev/null
+++ b/examples/qs_autoscale_master/output.tf
@@ -0,0 +1,58 @@
+output "Deployment" {
+ value = module.launch_qs_autoscale.Deployment
+}
+
+output "vpc_id" {
+ value = module.launch_vpc.vpc_id
+}
+output "public_subnets_ids_list" {
+ value = module.launch_vpc.public_subnets_ids_list
+}
+output "private_subnets_ids_list" {
+ value = module.launch_vpc.private_subnets_ids_list
+}
+output "public_rout_table" {
+ value = module.launch_vpc.public_rtb
+}
+
+output "management_name" {
+ value = module.launch_qs_autoscale.management_name
+}
+output "internal_port" {
+ value = module.launch_qs_autoscale.internal_port
+}
+output "load_balancer_url" {
+ value = module.launch_qs_autoscale.load_balancer_url
+}
+output "external_load_balancer_arn" {
+ value = module.launch_qs_autoscale.external_load_balancer_arn
+}
+output "internal_load_balancer_arn" {
+ value = module.launch_qs_autoscale.internal_load_balancer_arn
+}
+output "external_lb_target_group_arn" {
+ value = module.launch_qs_autoscale.external_lb_target_group_arn
+}
+output "internal_lb_target_group_arn" {
+ value = module.launch_qs_autoscale.internal_lb_target_group_arn
+}
+
+output "autoscale_autoscaling_group_name" {
+ value = module.launch_qs_autoscale.autoscale_autoscaling_group_name
+}
+output "autoscale_autoscaling_group_arn" {
+ value = module.launch_qs_autoscale.autoscale_autoscaling_group_arn
+}
+output "autoscale_security_group_id" {
+ value = module.launch_qs_autoscale.autoscale_security_group_id
+}
+output "autoscale_iam_role_name" {
+ value = module.launch_qs_autoscale.autoscale_iam_role_name
+}
+
+output "configuration_template" {
+ value = module.launch_qs_autoscale.configuration_template
+}
+output "controller_name" {
+ value = module.launch_qs_autoscale.controller_name
+}
diff --git a/examples/qs_autoscale_master/variables.tf b/examples/qs_autoscale_master/variables.tf
new file mode 100755
index 0000000..0b58899
--- /dev/null
+++ b/examples/qs_autoscale_master/variables.tf
@@ -0,0 +1,242 @@
+// Module: Check Point CloudGuard Network Quick Start Auto Scaling
+//Deploy a Check Point CloudGuard Network Security Gateways Auto Scaling Group, an external ALB/NLB, and optionally a Security Management Server and a web server Auto Scaling Group in a new VPC.
+
+// --- Environment ---
+variable "prefix" {
+ type = string
+ description = "(Optional) Instances name prefix"
+ default = ""
+ validation {
+ condition = length(var.prefix) <= 40
+ error_message = "Prefix can not exceed 40 characters."
+ }
+}
+variable "asg_name" {
+ type = string
+ description = "Autoscaling Group name"
+ default = "Check-Point-ASG-tf"
+ validation {
+ condition = length(var.asg_name) <= 100
+ error_message = "Autoscaling Group name can not exceed 100 characters."
+ }
+}
+// --- Network Configuration ---
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1} ) "
+}
+variable "private_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 2} ) "
+
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+
+// --- General Settings ---
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "provision_tag" {
+ type = string
+ description = "The tag is used by the Security Management Server to automatically provision the Security Gateways. Must be up to 12 alphanumeric characters and unique for each Quick Start deployment"
+ default = "quickstart"
+}
+variable "load_balancers_type" {
+ type = string
+ description = "Use Network Load Balancer if you wish to preserve the source IP address and Application Load Balancer if you wish to use content based routing"
+ default = "Network Load Balancer"
+}
+variable "load_balancer_protocol" {
+ type = string
+ description = "The protocol to use on the Load Balancer"
+}
+variable "certificate" {
+ type = string
+ description = "Amazon Resource Name (ARN) of an HTTPS Certificate, ignored if the selected protocol is HTTP"
+}
+variable "service_port" {
+ type = string
+ description = "The external Load Balancer listens to this port. Leave this field blank to use default ports: 80 for HTTP and 443 for HTTPS"
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+
+// --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_gateway_instance_type" {
+ source = "../../modules/instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "gateways_min_group_size" {
+ type = number
+ description = "The minimal number of Security Gateways"
+ default = 2
+}
+variable "gateways_max_group_size" {
+ type = number
+ description = "The maximal number of Security Gateways"
+ default = 10
+}
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../../modules/version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+
+// --- Check Point CloudGuard Network Security Management Server Configuration ---
+variable "management_deploy" {
+ type = bool
+ description = "Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section"
+ default = true
+}
+variable "management_instance_type" {
+ type = string
+ description = "The EC2 instance type of the Security Management Server"
+ default = "m5.xlarge"
+}
+module "validate_management_instance_type" {
+ source = "../../modules/instance_type"
+
+ chkp_type = "management"
+ instance_type = var.management_instance_type
+}
+variable "management_version" {
+ type = string
+ description = "The license to install on the Security Management Server"
+ default = "R81.20-BYOL"
+}
+module "validate_management_version" {
+ source = "../../modules/version_license"
+
+ chkp_type = "management"
+ version_license = var.management_version
+}
+variable "management_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "management_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "gateways_policy" {
+ type = string
+ description = "The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group"
+ default = "Standard"
+}
+variable "gateways_blades" {
+ type = bool
+ description = "Turn on the Intrusion Prevention System, Application Control, Anti-Virus and Anti-Bot Blades (additional Blades can be manually turned on later)"
+ default = true
+}
+variable "admin_cidr" {
+ type = string
+ description = "Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server"
+}
+variable "gateways_addresses" {
+ type = string
+ description = "Allow gateways only from this network to communicate with the Security Management Server"
+}
+
+// --- Web Servers Auto Scaling Group Configuration ---
+variable "servers_deploy" {
+ type = bool
+ description = "Select 'true' to deploy web servers and an internal Application Load Balancer. If you select 'false' the other parameters of this section will be ignored"
+ default = false
+}
+variable "servers_instance_type" {
+ type = string
+ description = "The EC2 instance type for the web servers"
+ default = "t3.micro"
+}
+module "validate_servers_instance_type" {
+ source = "../../modules/instance_type"
+
+ chkp_type = "server"
+ instance_type = var.servers_instance_type
+}
+variable "server_ami" {
+ type = string
+ description = "The Amazon Machine Image ID of a preconfigured web server (e.g. ami-0dc7dc63)"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
diff --git a/examples/qs_autoscale_master/versions.tf b/examples/qs_autoscale_master/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/examples/qs_autoscale_master/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/autoscale/README.md b/modules/autoscale/README.md
new file mode 100755
index 0000000..3cb176d
--- /dev/null
+++ b/modules/autoscale/README.md
@@ -0,0 +1,148 @@
+# Check Point CloudGuard Network Auto Scaling Terraform module for AWS
+
+Terraform module which deploys an Auto Scaling Group of Check Point Security Gateways into an existing VPC.
+
+These types of Terraform resources are supported:
+* [Launch template](https://www.terraform.io/docs/providers/aws/r/launch_template.html)
+* [Auto Scaling Group](https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html)
+* [Security group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [CloudWatch Metric Alarm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+* [Proxy Elastic Load Balancer](https://www.terraform.io/docs/providers/aws/r/elb.html) - conditional creation
+
+
+See the [CloudGuard Auto Scaling for AWS](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CloudGuard_Network_for_AWS_AutoScaling_DeploymentGuide/Default.htm) for additional information
+
+This solution uses the following modules:
+- amis
+
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/autoscale"
+ version = "1.0.2"
+
+ // --- Environment ---
+ prefix = "env1"
+ asg_name = "autoscaling_group"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ subnet_ids = ["subnet-abc123", "subnet-def456"]
+
+ // --- Automatic Provisioning with Security Management Server Settings ---
+ gateways_provision_address_type = "private"
+ management_server = "mgmt_env1"
+ configuration_template = "tmpl_env1"
+
+ // --- EC2 Instances Configuration ---
+ gateway_name = "asg_gateway"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ instances_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- Auto Scaling Configuration ---
+ minimum_group_size = 2
+ maximum_group_size = 10
+ target_groups = ["arn:aws:tg1/abc123", "arn:aws:tg2/def456"]
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ enable_instance_connect = false
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+
+ // --- Outbound Proxy Configuration (optional) ---
+ proxy_elb_type = "internet-facing"
+ proxy_elb_clients = "0.0.0.0/0"
+ proxy_elb_port = 8080
+}
+ ```
+
+- Conditional creation
+ - To enable cloudwatch for ASG:
+ ```
+ enable_cloudwatch = true
+ ```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To create an ASG configuration without a proxy ELB:
+ ```
+ proxy_elb_type= "none"
+ ```
+
+
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------|
+| prefix | (Optional) Instances name prefix | string | |
+| asg_name | Autoscaling Group name | string | |
+| vpc_id | The VPC ID in which to deploy | string | |
+| subnet_ids | List of public subnet IDs to launch resources into. Recommended at least 2 | list(string) | |
+| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address | string | - private
- public
**Default:** private |
+| management_server | The name that represents the Security Management Server in the CME configuration | string | |
+| configuration_template | Name of the provisioning template in the CME configuration | string | |
+| gateway_name | The name tag of the Security Gateways instances | string | **Default:** Check-Point-ASG-gateway-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| instances_tags | (Optional) A map of tags as key-value pairs. All tags will be added to all AutoScaling Group instances | map(string) | |
+| metadata_imdsv2_required | Set to true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| minimum_group_size | The minimum number of instances in the Auto Scaling group | number | **Default:** 2 |
+| maximum_group_size | The maximum number of instances in the Auto Scaling group | number | **Default:** 10 |
+| target_groups | (Optional) List of Target Group ARNs to associate with the Auto Scaling group | list(string) | |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command-line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| gateway_password_hash | (Optional) Admin user's password hash (use command `grub2-mkpasswd-pbkdf2` on Linux to generate a hash) | string | |
+| gateway_SICKey | Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters) | string | |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supported regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| allow_upload_download | Automatically download Blade Contracts and other important data to improve the product experience | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon-separated commands to run on the initial boot | string | |
+| proxy_elb_type | Type of ELB to create as an HTTP/HTTPS outbound proxy | string | - none
- internal
- internet-facing
**Default:** none |
+| proxy_elb_port | The TCP port on which the proxy will be listening | number | **Default:** 8080 |
+| proxy_elb_clients | The CIDR range of the clients of the proxy | string | **Default:** 0.0.0.0/0 |
+| gateway_maintenance_mode_password_hash | (Optional) Admin user's password and maintenance-mode password for recovery purposes. Use `grub2-mkpasswd-pbkdf2` on Linux to generate a password hash | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|------------------------------------------------|-------------------------------------------------------------------|
+| autoscale_autoscaling_group_name | The name of the deployed AutoScaling Group |
+| autoscale_autoscaling_group_arn | The ARN for the deployed AutoScaling Group |
+| autoscale_autoscaling_group_availability_zones | The AZs on which the Autoscaling Group is configured |
+| autoscale_autoscaling_group_desired_capacity | The deployed AutoScaling Group's desired capacity of instances |
+| autoscale_autoscaling_group_min_size | The deployed AutoScaling Group's minimum number of instances |
+| autoscale_autoscaling_group_max_size | The deployed AutoScaling Group's maximum number of instances |
+| autoscale_autoscaling_group_load_balancers | The deployed AutoScaling Group's configured load balancers |
+| autoscale_autoscaling_group_target_group_arns | The deployed AutoScaling Group's configured target groups |
+| autoscale_autoscaling_group_subnets | The subnets on which the deployed AutoScaling Group is configured |
+| autoscale_launch_template_id | The id of the Launch Template |
+| autoscale_autoscale_security_group_id | The deployed AutoScaling Group's security group id |
+| autoscale_iam_role_name | The deployed AutoScaling Group's IAM role name (if created) |
diff --git a/modules/autoscale/asg_userdata.yaml b/modules/autoscale/asg_userdata.yaml
new file mode 100755
index 0000000..c39c93a
--- /dev/null
+++ b/modules/autoscale/asg_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" installationType=\"autoscale\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"autoscale\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
diff --git a/modules/autoscale/locals.tf b/modules/autoscale/locals.tf
new file mode 100755
index 0000000..72fa595
--- /dev/null
+++ b/modules/autoscale/locals.tf
@@ -0,0 +1,62 @@
+locals {
+ asg_name = format("%s%s", var.prefix != "" ? format("%s-", var.prefix) : "", var.asg_name)
+ create_iam_role = var.enable_cloudwatch ? 1 : 0
+
+ gateways_provision_address_type_allowed_values = [
+ "public",
+ "private"
+ ]
+ // Will fail if var.gateways_provision_address_type is invalid
+ validate_gateways_provision_address_type = index(local.gateways_provision_address_type_allowed_values, var.gateways_provision_address_type)
+
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"
+ ]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SICKey is invalid
+ regex_sic_result = regex(local.regex_valid_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SICKey] must be at least 8 alphanumeric characters"
+
+ proxy_elb_type_allowed_values = [
+ "none",
+ "internal",
+ "internet-facing"
+ ]
+ // Will fail if var.proxy_elb_type is invalid
+ validate_proxy_elb_type = index(local.proxy_elb_type_allowed_values, var.proxy_elb_type)
+
+ regex_valid_cidr_range = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$"
+ // Will fail if var.proxy_elb_clients is invalid
+ regex_cidr_result = regex(local.regex_valid_cidr_range, var.proxy_elb_clients) == var.proxy_elb_clients ? 0 : "Variable [proxy_elb_clients] must be a valid CIDR range"
+
+ tags_asg_format = null_resource.tags_as_list_of_maps.*.triggers
+
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.gateway_version), 0)
+ gateway_bootstrap_script64 = base64encode(var.gateway_bootstrap_script)
+ gateway_password_hash_base64 = base64encode(var.gateway_password_hash)
+ maintenance_mode_password_hash_base64 = base64encode(var.gateway_maintenance_mode_password_hash)
+ gateway_SICkey_base64 = base64encode(var.gateway_SICKey)
+}
+resource "null_resource" "tags_as_list_of_maps" {
+ count = length(keys(var.instances_tags))
+
+ triggers = {
+ "key" = keys(var.instances_tags)[count.index]
+ "value" = values(var.instances_tags)[count.index]
+ "propagate_at_launch" = "true"
+ }
+}
\ No newline at end of file
diff --git a/modules/autoscale/main.tf b/modules/autoscale/main.tf
new file mode 100755
index 0000000..8fee0e9
--- /dev/null
+++ b/modules/autoscale/main.tf
@@ -0,0 +1,270 @@
+module "amis" {
+ source = "../amis"
+
+ version_license = var.gateway_version
+}
+
+resource "aws_security_group" "permissive_sg" {
+ name_prefix = format("%s_PermissiveSecurityGroup", local.asg_name)
+ description = "Permissive security group"
+ vpc_id = var.vpc_id
+
+ dynamic "ingress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "ingress"]
+ content {
+ from_port = ingress.value.from_port
+ to_port = ingress.value.to_port
+ protocol = ingress.value.protocol
+ cidr_blocks = ingress.value.cidr_blocks
+ }
+ }
+
+ dynamic ingress {
+ for_each = length([for rule in var.security_rules : rule if rule.direction == "ingress"]) == 0 ? [1] : []
+ content{
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ }
+
+ dynamic "egress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "egress"]
+ content {
+ from_port = egress.value.from_port
+ to_port = egress.value.to_port
+ protocol = egress.value.protocol
+ cidr_blocks = egress.value.cidr_blocks
+ }
+ }
+
+ dynamic egress {
+ for_each = length([for rule in var.security_rules : rule if rule.direction == "egress"]) == 0 ? [1] : []
+ content{
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ }
+ tags = {
+ Name = format("%s_PermissiveSecurityGroup", local.asg_name)
+ }
+}
+
+resource "aws_launch_template" "asg_launch_template" {
+ name_prefix = local.asg_name
+ image_id = module.amis.ami_id
+ instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ network_interfaces {
+ associate_public_ip_address = true
+ security_groups = [aws_security_group.permissive_sg.id]
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ iam_instance_profile {
+ name = ( var.enable_cloudwatch ? aws_iam_instance_profile.instance_profile[0].name : "")
+ }
+ monitoring {
+ enabled = true
+ }
+
+ block_device_mappings {
+ device_name = "/dev/xvda"
+ ebs {
+ volume_type = "gp3"
+ volume_size = var.volume_size
+ encrypted = var.enable_volume_encryption
+ }
+ }
+ description = "Initial template version"
+
+
+ user_data = base64encode(templatefile("${path.module}/asg_userdata.yaml", {
+ // script's arguments
+ PasswordHash = local.gateway_password_hash_base64,
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64
+ EnableCloudWatch = var.enable_cloudwatch,
+ EnableInstanceConnect = var.enable_instance_connect,
+ Shell = var.admin_shell,
+ SICKey = local.gateway_SICkey_base64,
+ AllowUploadDownload = var.allow_upload_download,
+ BootstrapScript = local.gateway_bootstrap_script64,
+ OsVersion = local.version_split
+ }))
+}
+resource "aws_autoscaling_group" "asg" {
+ name_prefix = local.asg_name
+ launch_template {
+ id = aws_launch_template.asg_launch_template.id
+ version = aws_launch_template.asg_launch_template.latest_version
+ }
+ min_size = var.minimum_group_size
+ max_size = var.maximum_group_size
+ load_balancers = aws_elb.proxy_elb.*.name
+ target_group_arns = var.target_groups
+ vpc_zone_identifier = var.subnet_ids
+ health_check_grace_period = 3600
+ health_check_type = "ELB"
+
+ tag {
+ key = "Name"
+ value = format("%s%s", var.prefix != "" ? format("%s-", var.prefix) : "", var.gateway_name)
+ propagate_at_launch = true
+ }
+
+ tag {
+ key = "x-chkp-tags"
+ value = format("management=%s:template=%s:ip-address=%s", var.management_server, var.configuration_template, var.gateways_provision_address_type)
+ propagate_at_launch = true
+ }
+
+ dynamic "tag" {
+ for_each = var.instances_tags
+ content {
+ key = tag.key
+ value = tag.value
+ propagate_at_launch = true
+ }
+ }
+}
+
+data "aws_iam_policy_document" "assume_role_policy_document" {
+ version = "2012-10-17"
+ statement {
+ actions = ["sts:AssumeRole"]
+ principals {
+ type = "Service"
+ identifiers = ["ec2.amazonaws.com"]
+ }
+ effect = "Allow"
+ }
+}
+
+resource "aws_iam_role" "role" {
+ count = local.create_iam_role
+ name_prefix = format("%s-iam_role", local.asg_name)
+ assume_role_policy = data.aws_iam_policy_document.assume_role_policy_document.json
+ path = "/"
+}
+module "attach_cloudwatch_policy" {
+ source = "../cloudwatch_policy"
+ count = local.create_iam_role
+ role = aws_iam_role.role[count.index].name
+ tag_name = local.asg_name
+}
+
+resource "aws_iam_instance_profile" "instance_profile" {
+ count = local.create_iam_role
+ name_prefix = format("%s-iam_instance_profile", local.asg_name)
+ path = "/"
+ role = aws_iam_role.role[count.index].name
+}
+
+// Proxy ELB
+locals {
+ proxy_elb_condition = var.proxy_elb_type != "none" ? 1 : 0
+}
+resource "random_id" "proxy_elb_uuid" {
+ byte_length = 5
+}
+resource "aws_elb" "proxy_elb" {
+ count = local.proxy_elb_condition
+ name = format("%s-proxy-elb-%s", var.prefix, random_id.proxy_elb_uuid.hex)
+ internal = var.proxy_elb_type == "internal"
+ cross_zone_load_balancing = true
+ listener {
+ instance_port = var.proxy_elb_port
+ instance_protocol = "TCP"
+ lb_port = var.proxy_elb_port
+ lb_protocol = "TCP"
+ }
+ health_check {
+ target = format("TCP:%s", var.proxy_elb_port)
+ healthy_threshold = 3
+ unhealthy_threshold = 5
+ interval = 30
+ timeout = 5
+ }
+ subnets = var.subnet_ids
+ security_groups = [aws_security_group.elb_security_group[count.index].id]
+}
+resource "aws_load_balancer_policy" "proxy_elb_policy" {
+ count = local.proxy_elb_condition
+ load_balancer_name = aws_elb.proxy_elb[count.index].name
+ policy_name = "EnableProxyProtocol"
+ policy_type_name = "ProxyProtocolPolicyType"
+
+ policy_attribute {
+ name = "ProxyProtocol"
+ value = "true"
+ }
+}
+resource "aws_security_group" "elb_security_group" {
+ count = local.proxy_elb_condition
+ description = "ELB security group"
+ vpc_id = var.vpc_id
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ ingress {
+ protocol = "tcp"
+ cidr_blocks = [var.proxy_elb_clients]
+ from_port = var.proxy_elb_port
+ to_port = var.proxy_elb_port
+ }
+}
+
+// Scaling metrics
+resource "aws_cloudwatch_metric_alarm" "cpu_alarm_low" {
+ alarm_name = format("%s_alarm_low", aws_autoscaling_group.asg.name)
+ metric_name = "CPUUtilization"
+ alarm_description = "Scale-down if CPU < 60% for 10 minutes"
+ namespace = "AWS/EC2"
+ statistic = "Average"
+ period = 300
+ evaluation_periods = 2
+ threshold = 60
+ alarm_actions = [aws_autoscaling_policy.scale_down_policy.arn]
+ dimensions = {
+ AutoScalingGroupName = aws_autoscaling_group.asg.name
+ }
+ comparison_operator = "LessThanThreshold"
+}
+resource "aws_autoscaling_policy" "scale_down_policy" {
+ autoscaling_group_name = aws_autoscaling_group.asg.name
+ name = format("%s_scale_down", aws_autoscaling_group.asg.name)
+ adjustment_type = "ChangeInCapacity"
+ cooldown = 300
+ scaling_adjustment = -1
+}
+resource "aws_cloudwatch_metric_alarm" "cpu_alarm_high" {
+ alarm_name = format("%s_alarm_high", aws_autoscaling_group.asg.name)
+ metric_name = "CPUUtilization"
+ alarm_description = "Scale-up if CPU > 80% for 10 minutes"
+ namespace = "AWS/EC2"
+ statistic = "Average"
+ period = 300
+ evaluation_periods = 2
+ threshold = 80
+ alarm_actions = [aws_autoscaling_policy.scale_up_policy.arn]
+ dimensions = {
+ AutoScalingGroupName = aws_autoscaling_group.asg.name
+ }
+ comparison_operator = "GreaterThanThreshold"
+}
+resource "aws_autoscaling_policy" "scale_up_policy" {
+ autoscaling_group_name = aws_autoscaling_group.asg.name
+ name = format("%s_scale_up", aws_autoscaling_group.asg.name)
+ adjustment_type = "ChangeInCapacity"
+ cooldown = 300
+ scaling_adjustment = 1
+}
diff --git a/modules/autoscale/output.tf b/modules/autoscale/output.tf
new file mode 100755
index 0000000..152bb74
--- /dev/null
+++ b/modules/autoscale/output.tf
@@ -0,0 +1,43 @@
+output "Deployment" {
+ value = "Finalizing instances configuration may take up to 20 minutes after deployment is finished."
+}
+
+output "autoscale_autoscaling_group_name" {
+ value = aws_autoscaling_group.asg.name
+}
+output "autoscale_autoscaling_group_arn" {
+ value = aws_autoscaling_group.asg.arn
+}
+output "autoscale_autoscaling_group_availability_zones" {
+ value = aws_autoscaling_group.asg.availability_zones
+}
+output "autoscale_autoscaling_group_desired_capacity" {
+ value = aws_autoscaling_group.asg.desired_capacity
+}
+output "autoscale_autoscaling_group_min_size" {
+ value = aws_autoscaling_group.asg.min_size
+}
+output "autoscale_autoscaling_group_max_size" {
+ value = aws_autoscaling_group.asg.max_size
+}
+output "autoscale_autoscaling_group_load_balancers" {
+ value = aws_autoscaling_group.asg.load_balancers
+}
+output "autoscale_autoscaling_group_target_group_arns" {
+ value = aws_autoscaling_group.asg.target_group_arns
+}
+output "autoscale_autoscaling_group_subnets" {
+ value = aws_autoscaling_group.asg.vpc_zone_identifier
+}
+output "autoscale_launch_template_id" {
+ value = aws_launch_template.asg_launch_template.id
+}
+
+output "autoscale_security_group_id" {
+ value = aws_security_group.permissive_sg.id
+}
+
+output "autoscale_iam_role_name" {
+ value = aws_iam_role.role.*.name
+}
+
diff --git a/modules/autoscale/variables.tf b/modules/autoscale/variables.tf
new file mode 100755
index 0000000..b62e619
--- /dev/null
+++ b/modules/autoscale/variables.tf
@@ -0,0 +1,192 @@
+// Module: Check Point CloudGuard Network Auto Scaling Group into an existing VPC
+
+// --- Environment ---
+variable "prefix" {
+ type = string
+ description = "(Optional) Instances name prefix"
+ default = ""
+ validation {
+ condition = length(var.prefix) <= 40
+ error_message = "Prefix can not exceed 40 characters."
+ }
+}
+variable "asg_name" {
+ type = string
+ description = "Autoscaling Group name"
+ default = "Check-Point-ASG-tf"
+ validation {
+ condition = length(var.asg_name) <= 100
+ error_message = "Autoscaling Group name can not exceed 100 characters."
+ }
+}
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "subnet_ids" {
+ type = list(string)
+ description = "List of public subnet IDs to launch resources into. Recommended at least 2"
+}
+
+// --- Automatic Provisioning with Security Management Server Settings ---
+variable "gateways_provision_address_type" {
+ type = string
+ description = "Determines if the gateways are provisioned using their private or public address"
+ default = "private"
+}
+variable "management_server" {
+ type = string
+ description = "The name that represents the Security Management Server in the CME configuration"
+}
+variable "configuration_template" {
+ type = string
+ description = "Name of the provisioning template in the CME configuration"
+ validation {
+ condition = length(var.configuration_template) < 31
+ error_message = "The configuration_template name can not exceed 30 characters."
+ }
+}
+
+// --- EC2 Instances Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "The name tag of the Security Gateways instances"
+ default = "Check-Point-ASG-gateway-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Will fail if var.volume_size is less than 100
+ count = var.volume_size >= 100 ? 0 : "variable volume_size must be at least 100"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "instances_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added on all AutoScaling Group instances"
+ default = {}
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+
+// --- Auto Scaling Configuration ---
+variable "minimum_group_size" {
+ type = number
+ description = "The minimum number of instances in the Auto Scaling group"
+ default = 2
+}
+variable "maximum_group_size" {
+ type = number
+ description = "The maximum number of instances in the Auto Scaling group"
+ default = 10
+}
+variable "target_groups" {
+ type = list(string)
+ description = "(Optional) List of Target Group ARNs to associate with the Auto Scaling group"
+ default = []
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters)"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) Semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+
+// --- (Optional) Outbound Proxy Configuration ---
+variable "proxy_elb_type" {
+ type = string
+ description = "Type of ELB to create as an HTTP/HTTPS outbound proxy"
+ default = "none"
+}
+variable "proxy_elb_port" {
+ type = number
+ description = "The TCP port on which the proxy will be listening"
+ default = 8080
+}
+variable "proxy_elb_clients" {
+ type = string
+ description = "The CIDR range of the clients of the proxy"
+ default = "0.0.0.0/0"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/autoscale/versions.tf b/modules/autoscale/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/autoscale/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/autoscale_gwlb/README.md b/modules/autoscale_gwlb/README.md
index f77eebf..97b8b67 100755
--- a/modules/autoscale_gwlb/README.md
+++ b/modules/autoscale_gwlb/README.md
@@ -18,40 +18,101 @@ This solution uses the following modules:
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/autoscale_gwlb"
+ version = "1.0.2"
+
+ // --- Environment ---
+ prefix = "env1"
+ asg_name = "autoscaling_group"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ subnet_ids = ["subnet-abc123", "subnet-def456"]
+
+ // --- Automatic Provisioning with Security Management Server Settings ---
+ gateways_provision_address_type = "private"
+ allocate_public_IP = false
+ management_server = "mgmt_env1"
+ configuration_template = "tmpl_env1"
+
+ // --- EC2 Instances Configuration ---
+ gateway_name = "asg_gateway"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ instances_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- Auto Scaling Configuration ---
+ minimum_group_size = 2
+ maximum_group_size = 10
+ target_groups = ["arn:aws:tg1/abc123", "arn:aws:tg2/def456"]
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ enable_instance_connect = false
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+}
+```
+
+
## Inputs
-| Name | Description | Type | Allowed Values |
-|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|------------------------------------------------------------------------------------------------------------------|
-| prefix | (Optional) Instances name prefix | string | |
-| asg_name | Autoscaling Group name | string | |
-| vpc_id | The VPC id in which to deploy | string | |
-| subnet_ids | List of public subnet IDs to launch resources into. Recommended at least 2 | list(string)| |
-| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address. | string | - private
- public
**Default:** private |
-| allocate_public_IP | Allocate a Public IP for gateway members. | bool | true/false
**Default:** false |
-| management_server | The name that represents the Security Management Server in the CME configuration | string | |
-| configuration_template | Name of the provisioning template in the CME configuration | string | |
-| gateway_name | The name tag of the Security Gateways instances | string |
**Default:** Check-Point-ASG-gateway-tf |
-| gateway_instance_type | The instance type of the Security Gateways | string | - c5.large
- c5.xlarge
- m6a.large
- c6i.xlarge
**Default:** c5.xlarge |
-| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
-| volume_size | Root volume size (GB) - minimum 100 | number |
**Default:** 100 |
-| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
-| instances_tags | (Optional) A map of tags as key=value pairs. All tags will be added on all AutoScaling Group instances | map(string)|
**Default:** {} |
-| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
-| minimum_group_size | The minimum number of instances in the Auto Scaling group | number |
**Default:** 2 |
-| maximum_group_size | The maximum number of instances in the Auto Scaling group | number |
**Default:** 10 |
-| target_groups | (Optional) List of Target Group ARNs to associate with the Auto Scaling group | list(string)| |
-| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
-| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
-| gateway_password_hash | (Optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. | string | |
-| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters) | string |
**Default:** "12345678" |
-| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
-| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false
**Default:** true |
-| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
-| gateway_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | |
-| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
-| gateway_maintenance_mode_password_hash | (Optional) Maintenance-mode password for recovery purposes. | string | |
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------|
+| prefix | (Optional) Instances name prefix | string | |
+| asg_name | Autoscaling Group name | string | **Default:** Check-Point-ASG-tf|
+| vpc_id | The VPC ID in which to deploy | string | |
+| subnet_ids | List of public subnet IDs to launch resources into. Recommended at least 2 | list(string) | |
+| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address. | string | - private
- public
**Default:** private |
+| allocate_public_IP | Allocate a Public IP for gateway members. | bool | true/false
**Default:** false |
+| management_server | The name that represents the Security Management Server in the CME configuration | string | |
+| configuration_template | Name of the provisioning template in the CME configuration | string | |
+| gateway_name | The name tag of the Security Gateways instances | string | **Default:** Check-Point-ASG-gateway-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| instances_tags | (Optional) A map of tags as key=value pairs. All tags will be added to all AutoScaling Group instances | map(string) | **Default:** {} |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| minimum_group_size | The minimum number of instances in the Auto Scaling group | number | **Default:** 2 |
+| maximum_group_size | The maximum number of instances in the Auto Scaling group | number | **Default:** 10 |
+| target_groups | (Optional) List of Target Group ARNs to associate with the Auto Scaling group | list(string) | |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| gateway_password_hash | (Optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. | string | |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters) | string | **Default:** "12345678" |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| gateway_maintenance_mode_password_hash | (Optional) Maintenance-mode password for recovery purposes. | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|------------------------------------------------|-------------------------------------------------------------------|
| autoscale_autoscaling_group_name | The name of the deployed AutoScaling Group |
diff --git a/modules/autoscale_gwlb/asg_userdata.yaml b/modules/autoscale_gwlb/asg_userdata.yaml
index 8cc2a7a..13f5564 100755
--- a/modules/autoscale_gwlb/asg_userdata.yaml
+++ b/modules/autoscale_gwlb/asg_userdata.yaml
@@ -26,4 +26,4 @@ bootcmd:
- echo "cpprod_util CPPROD_SetValue \"fw1\" \"AwsGwlb\" 4 1 1" >> /etc/rc.local
runcmd:
- |
- python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" installationType=\"autoscale\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"20241027\" templateName=\"autoscale_gwlb\" templateType=\"terraform\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
\ No newline at end of file
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" installationType=\"autoscale\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"autoscale_gwlb\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
\ No newline at end of file
diff --git a/modules/autoscale_gwlb/main.tf b/modules/autoscale_gwlb/main.tf
index 218ac23..c657fdb 100755
--- a/modules/autoscale_gwlb/main.tf
+++ b/modules/autoscale_gwlb/main.tf
@@ -10,17 +10,45 @@ resource "aws_security_group" "permissive_sg" {
name_prefix = format("%s_PermissiveSecurityGroup", local.asg_name)
description = "Permissive security group"
vpc_id = var.vpc_id
- egress {
- from_port = 0
- to_port = 0
- protocol = "-1"
- cidr_blocks = ["0.0.0.0/0"]
- }
- ingress {
- from_port = 0
- to_port = 0
- protocol = "-1"
- cidr_blocks = ["0.0.0.0/0"]
+
+ dynamic "ingress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "ingress"]
+ content {
+ from_port = ingress.value.from_port
+ to_port = ingress.value.to_port
+ protocol = ingress.value.protocol
+ cidr_blocks = ingress.value.cidr_blocks
+ }
+ }
+
+ dynamic ingress {
+ for_each = length([for rule in var.security_rules : rule if rule.direction == "ingress"]) == 0 ? [1] : []
+ content{
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ }
+
+ dynamic "egress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "egress"]
+ content {
+ from_port = egress.value.from_port
+ to_port = egress.value.to_port
+ protocol = egress.value.protocol
+ cidr_blocks = egress.value.cidr_blocks
+ }
+ }
+
+ dynamic egress {
+ for_each = length([for rule in var.security_rules : rule if rule.direction == "egress"]) == 0 ? [1] : []
+ content{
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
}
tags = {
Name = format("%s_PermissiveSecurityGroup", local.asg_name)
diff --git a/modules/autoscale_gwlb/variables.tf b/modules/autoscale_gwlb/variables.tf
index 0a57428..6262fe8 100755
--- a/modules/autoscale_gwlb/variables.tf
+++ b/modules/autoscale_gwlb/variables.tf
@@ -5,11 +5,15 @@ variable "prefix" {
type = string
description = "(Optional) Instances name prefix"
default = ""
+ validation {
+ condition = length(var.prefix) <= 40
+ error_message = "Prefix can not exceed 40 characters."
+ }
}
variable "asg_name" {
type = string
description = "Autoscaling Group name"
- default = "Check-Point-Security-Gateway-AutoScaling-Group-tf"
+ default = "Check-Point-ASG-tf"
validation {
condition = length(var.asg_name) <= 100
error_message = "Autoscaling Group name can not exceed 100 characters."
@@ -68,7 +72,7 @@ variable "gateway_instance_type" {
default = "c6in.xlarge"
}
module "validate_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "gateway"
instance_type = var.gateway_instance_type
@@ -126,7 +130,7 @@ variable "gateway_version" {
default = "R81.20-BYOL"
}
module "validate_gateway_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "gwlb_gw"
version_license = var.gateway_version
@@ -175,4 +179,15 @@ variable "volume_type" {
type = string
description = "General Purpose SSD Volume Type"
default = "gp3"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
}
\ No newline at end of file
diff --git a/modules/cluster/README.md b/modules/cluster/README.md
new file mode 100755
index 0000000..2138ebf
--- /dev/null
+++ b/modules/cluster/README.md
@@ -0,0 +1,147 @@
+# Check Point CloudGuard Network Security Cluster Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Cluster into an existing VPC on AWS.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html) - conditional creation
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html) - conditional creation
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Deploying a Check Point Cluster in AWS (Amazon Web Services)](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk104418) for additional information
+
+This solution uses the following modules:
+- amis
+- cluster_iam_role
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/cluster"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ public_subnet_id = "subnet-123456"
+ private_subnet_id = "subnet-345678"
+ private_route_table = "rtb-12345678"
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Cluster-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+ predefined_role = ""
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ memberAToken = ""
+ memberBToken = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+}
+ ```
+
+- Conditional creation
+ - To create an Elastic IP and associate it to each cluster member instance:
+ ```
+ allocate_and_associate_eip = "true"
+ ```
+ - To create IAM Role:
+ ```
+ predefined_role = ""
+ ```
+ - To create route from '0.0.0.0/0' to the Active Cluster member instance, please provide route table:
+ ```
+ private_route_table = "rtb-12345678"
+ ```
+
+ ### Optional re-deploy of cluster member:
+ In case of re-deploying one cluster member, make sure that it's in STANDBY state, and the second member is the ACTIVE one.
+ Follow the commands below in order to re-deploy (replace MEMBER with a or b):
+ - terraform taint aws_instance.member-MEMBER-instance
+ - terraform plan (review the changes)
+ - terraform apply
+ - In Smart Console: reset SIC with the re-deployed member and install policy
+
+## Inputs
+# Parameters Description
+
+| Name | Description | Type | Allowed values |
+|------|-------------|------|----------------|
+| **vpc_id** | The VPC ID in which to deploy | string | Required |
+| **public_subnet_id** | The public subnet of the cluster. The cluster's public IPs will be generated from this subnet | string | Required |
+| **private_subnet_id** | The private subnet of the cluster. The cluster's private IPs will be generated from this subnet | string | Required |
+| **private_route_table** | (Optional) Set 0.0.0.0/0 route to the Active Cluster member instance in this route table (e.g. rtb-12a34567). Route table cannot have an existing 0.0.0.0/0 route | string | **Default:** "" |
+| **gateway_name** | (Optional) The name tag of the Security Gateway instances | string | **Default:** "Check-Point-Cluster-tf" |
+| **gateway_instance_type** | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** "c5.xlarge" |
+| **key_name** | The EC2 Key Pair name to allow SSH access to the instance | string | Required |
+| **allocate_and_associate_eip** | If true, an Elastic IP will be allocated and associated with each cluster member, in addition to the shared cluster Elastic IP | bool | true;
false.
**Default:** true |
+| **volume_size** | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| **volume_encryption** | KMS or CMK key identifier. Use key ID, alias, or ARN. Key alias should be prefixed with 'alias/' | string | **Default:** "alias/aws/ebs" |
+| **enable_instance_connect** | Enable AWS Instance Connect. Supported regions are listed [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true;
false.
**Default:** false |
+| **disable_instance_termination** | Prevents an instance from accidental termination. Note: Setting this true may prevent `terraform destroy` from working properly | bool | true;
false.
**Default:** false |
+| **metadata_imdsv2_required** | Set true to deploy the instance with metadata v2 token required | bool | true;
false.
**Default:** true
Required |
+| **instance_tags** | (Optional) A map of tags as key=value pairs. Tags will be added to the Gateway EC2 instances | map(string) | **Default:** {} |
+| **predefined_role** | (Optional) A predefined IAM role to attach to the cluster profile | string | **Default:** "" |
+| **gateway_version** | Gateway version and license | string | "R81.10-BYOL";
"R81.20-BYOL";
"R82-BYOL".
**Default:** "R81.20-BYOL" |
+| **admin_shell** | Set the admin shell to enable advanced command line configuration | string | "/etc/cli.sh";
"/bin/bash";
"/bin/csh".
**Default:** "/etc/cli.sh" |
+| **gateway_SICKey** | The Secure Internal Communication key for trusted connection between Check Point components. Must be at least 8 alphanumeric characters | string | **Default:** "12345678" |
+| **gateway_password_hash** | (Optional) Admin user's password hash (use `openssl passwd -6 PASSWORD` to generate) | string | **Default:** "" |
+| **memberAToken** | (Recommended) Token for quick connection to Smart-1 Cloud. Instructions in SK180501 | string | **Default:** "" |
+| **memberBToken** | (Recommended) Token for quick connection to Smart-1 Cloud. Instructions in SK180501 | string | **Default:** "" |
+| **resources_tag_name** | (Optional) Name tag prefix for resources | string | **Default:** "" |
+| **gateway_hostname** | (Optional) Hostname will append 'member-a' or 'member-b' accordingly. Cannot contain reserved words (see SK40179 for details) | string | **Default:** "" |
+| **allow_upload_download** | Automatically download Blade Contracts and other important data to enhance product experience | bool | true;
false.
**Default:** true |
+| **enable_cloudwatch** | Report Check Point-specific CloudWatch metrics | bool | true;
false.
**Default:** false |
+| **gateway_bootstrap_script** | (Optional) Semicolon (;) separated commands to run on the initial boot | string | **Default:** "" |
+| **primary_ntp** | (Optional) IPv4 address of the primary Network Time Protocol server | string | **Default:** "169.254.169.123" |
+| **secondary_ntp** | (Optional) IPv4 address of the secondary Network Time Protocol server | string | **Default:** "0.pool.ntp.org" |
+| **gateway_maintenance_mode_password_hash** | (Optional) Maintenance-mode password hash (generate using `grub2-mkpasswd-pbkdf2` on Linux) | string | **Default:** "" |
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------|-----------------------------------------------------|
+| ami_id | The ami id of the deployed Security Cluster members |
+| cluster_public_ip | The public address of the cluster |
+| member_a_public_ip | The public address of member A |
+| member_b_public_ip | The public address of member B |
+| member_a_ssh | SSH command to member A |
+| member_b_ssh | SSH command to member B |
+| member_a_url | URL to the member A portal |
+| member_b_url | URL to the member B portal |
diff --git a/modules/cluster/cluster_member_a_userdata.yaml b/modules/cluster/cluster_member_a_userdata.yaml
new file mode 100755
index 0000000..63c12ad
--- /dev/null
+++ b/modules/cluster/cluster_member_a_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" "smart1CloudToken=\"${TokenA}\"" installationType=\"cluster\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" elasticIp=\"${MemberAPublicAddress}\" templateVersion=\"1.0.2\" templateName=\"cluster\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname}\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" allocatePublicAddress=\"${AllocateAddress}\" bootstrapScript64=\"${GatewayBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/cluster/cluster_member_b_userdata.yaml b/modules/cluster/cluster_member_b_userdata.yaml
new file mode 100755
index 0000000..8d6082e
--- /dev/null
+++ b/modules/cluster/cluster_member_b_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" "smart1CloudToken=\"${TokenB}\"" installationType=\"cluster\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" elasticIp=\"${MemberBPublicAddress}\" templateVersion=\"1.0.2\" templateName=\"cluster\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" allocatePublicAddress=\"${AllocateAddress}\" bootstrapScript64=\"${GatewayBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/cluster/locals.tf b/modules/cluster/locals.tf
new file mode 100755
index 0000000..d64b39e
--- /dev/null
+++ b/modules/cluster/locals.tf
@@ -0,0 +1,69 @@
+locals {
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ enable_cloudwatch_policy = var.enable_cloudwatch ? 1 : 0
+ create_iam_role = var.predefined_role == "" ? 1 : 0
+ provided_roue_table = var.private_route_table == "" ? 0 : 1
+ internal_route_table_condition = var.private_route_table != "" ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ regex_token_valid = "(^https://(.+).checkpoint.com/app/maas/api/v1/tenant(.+)|^$)"
+ //TokenA: will fail if decode token should contain https:// and .checkpoint.com/app/maas/api/v1/tenant or empty string
+ split_tokenA = split(" ", var.memberAToken)
+ tokenA_decode = base64decode(element(local.split_tokenA, length(local.split_tokenA)-1))
+ regex_tokenA = regex(local.regex_token_valid, local.tokenA_decode) == local.tokenA_decode ? 0 : "Smart-1 Cloud token A is invalid format"
+
+ //TokenB: will fail if decode token should contain https:// and .checkpoint.com/app/maas/api/v1/tenant or empty string
+ split_tokenB = split(" ", var.memberBToken)
+ tokenB_decode = base64decode(element(local.split_tokenB, length(local.split_tokenB)-1))
+ regex_tokenB = regex(local.regex_token_valid, local.tokenB_decode) == local.tokenB_decode ? 0 : "Smart-1 Cloud token B is invalid format"
+
+ is_both_tokens_used = length(var.memberAToken) > 0 == length(var.memberBToken) > 0
+ validation_message_both = "Smart-1 Cloud Tokens for member A and member B can not be empty."
+ //Will fail if var.memberAToken is empty and var.memberBToken isn't and vice versa
+ regex_s1c_validate = regex("^$", (local.is_both_tokens_used ? "" : local.validation_message_both))
+
+ is_tokens_used = length(var.memberAToken) > 0
+ is_both_tokens_the_same = var.memberAToken == var.memberBToken
+ validation_message_unique = "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
+ //Will fail if both s1c tokens are the same
+ regex_s1c_unique = local.is_tokens_used ? regex("^$", (local.is_both_tokens_the_same ? local.validation_message_unique : "")) : ""
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.gateway_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.gateway_hostname) == var.gateway_hostname ? 0 : "Variable [gateway_hostname] must be a valid hostname label or an empty string"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.gateway_version), 0)
+
+ gateway_bootstrap_script64 = base64encode(var.gateway_bootstrap_script)
+ gateway_SICkey_base64 = base64encode(var.gateway_SICKey)
+ gateway_password_hash_base64=base64encode(var.gateway_password_hash)
+ maintenance_mode_password_hash_base64 = base64encode(var.gateway_maintenance_mode_password_hash)
+}
diff --git a/modules/cluster/main.tf b/modules/cluster/main.tf
new file mode 100755
index 0000000..8b4ab11
--- /dev/null
+++ b/modules/cluster/main.tf
@@ -0,0 +1,287 @@
+
+
+module "amis" {
+ source = "../amis"
+
+ version_license = var.gateway_version
+ chkp_type = "gateway"
+}
+
+module "common_permissive_sg" {
+ source = "../permissive_sg"
+ security_rules = var.security_rules
+ vpc_id = var.vpc_id
+ resources_tag_name = var.resources_tag_name
+ gateway_name = var.gateway_name
+}
+
+resource "aws_iam_instance_profile" "cluster_instance_profile" {
+ path = "/"
+ role = local.create_iam_role == 1 ? join("", module.cluster_iam_role.*.cluster_iam_role_name) : var.predefined_role
+}
+
+module "cluster_iam_role" {
+ source = "../cluster_iam_role"
+ count = local.create_iam_role
+}
+
+module "attach_cloudwatch_policy" {
+ source = "../cloudwatch_policy"
+ count = local.enable_cloudwatch_policy
+ role = aws_iam_instance_profile.cluster_instance_profile.role
+ tag_name = var.resources_tag_name != "" ? var.resources_tag_name : var.gateway_name
+}
+
+resource "aws_network_interface" "member_a_external_eni" {
+ subnet_id = var.public_subnet_id
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member A external"
+ source_dest_check = false
+ lifecycle {
+ ignore_changes = [private_ips_count,]
+ }
+ private_ips_count = 1
+ tags = {
+ Name = format("%s-Member_A_ExternalInterface", var.resources_tag_name != "" ? var.resources_tag_name : var.gateway_name) }
+}
+
+resource "aws_network_interface" "member_b_external_eni" {
+ subnet_id = var.public_subnet_id
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member B external"
+ source_dest_check = false
+ tags = {
+ Name = format("%s-Member_B_ExternalInterface", var.resources_tag_name != "" ? var.resources_tag_name : var.gateway_name) }
+}
+
+resource "aws_network_interface" "member_a_internal_eni" {
+ subnet_id = var.private_subnet_id
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member A internal"
+ source_dest_check = false
+ lifecycle {
+ ignore_changes = [private_ips_count,]
+ }
+ private_ips_count = 1
+ tags = {
+ Name = format("%s-Member_A_InternalInterface", var.resources_tag_name != "" ? var.resources_tag_name : var.gateway_name) }
+}
+
+resource "aws_network_interface" "member_b_internal_eni" {
+ subnet_id = var.private_subnet_id
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member B internal"
+ source_dest_check = false
+ tags = {
+ Name = format("%s-Member_B_InternalInterface", var.resources_tag_name != "" ? var.resources_tag_name : var.gateway_name) }
+}
+
+resource "aws_route" "internal_default_route" {
+ count = local.internal_route_table_condition
+ route_table_id = var.private_route_table
+ lifecycle {
+ ignore_changes = [network_interface_id,]
+ }
+ destination_cidr_block = "0.0.0.0/0"
+ network_interface_id = aws_network_interface.member_a_internal_eni.id
+}
+
+resource "aws_route_table_association" "private_rtb_to_private_subnet" {
+ count = var.private_route_table == "" ? 0 : 1
+ route_table_id = var.private_route_table
+ subnet_id = var.private_subnet_id
+}
+
+resource "aws_launch_template" "member_a_launch_template" {
+ instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ image_id = module.amis.ami_id
+ description = "Initial launch template version"
+
+ iam_instance_profile {
+ name = aws_iam_instance_profile.cluster_instance_profile.id
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_a_external_eni.id
+ device_index = 0
+ }
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_a_internal_eni.id
+ device_index = 1
+ }
+}
+
+resource "aws_launch_template" "member_b_launch_template" {
+ instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ image_id = module.amis.ami_id
+ description = "Initial launch template version"
+
+ iam_instance_profile {
+ name = aws_iam_instance_profile.cluster_instance_profile.id
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_b_external_eni.id
+ device_index = 0
+ }
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_b_internal_eni.id
+ device_index = 1
+ }
+}
+
+resource "aws_instance" "member-a-instance" {
+ depends_on = [
+ aws_network_interface.member_a_external_eni,
+ aws_network_interface.member_a_internal_eni
+ ]
+
+ launch_template {
+ id = aws_launch_template.member_a_launch_template.id
+ version = "$Latest"
+ }
+
+ disable_api_termination = var.disable_instance_termination
+
+ tags = merge({
+ Name = format("%s-Member-A",var.gateway_name),
+ x-chkp-member-ips = format("public-ip=%s:external-private-ip=%s:internal-private-ip=%s",
+ var.allocate_and_associate_eip ? aws_eip.member_a_eip[0].public_ip : "", aws_network_interface.member_a_external_eni.private_ip,aws_network_interface.member_a_internal_eni.private_ip),
+ x-chkp-cluster-ips = format("cluster-ip=%s:cluster-eth0-private-ip=%s:cluster-eth1-private-ip=%s",
+ aws_eip.cluster_eip.public_ip, element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0),
+ element(tolist(setsubtract(tolist(aws_network_interface.member_a_internal_eni.private_ips), [aws_network_interface.member_a_internal_eni.private_ip])), 0))
+ }, var.instance_tags)
+
+ ebs_block_device {
+ device_name = "/dev/xvda"
+ volume_type = "gp2"
+ volume_size = var.volume_size
+ encrypted = local.volume_encryption_condition
+ kms_key_id = local.volume_encryption_condition ? var.volume_encryption : ""
+ }
+
+ lifecycle {
+ ignore_changes = [ebs_block_device,]
+ }
+
+ user_data = templatefile("${path.module}/cluster_member_a_userdata.yaml", {
+ // script's arguments
+ Hostname = var.gateway_hostname,
+ PasswordHash = local.gateway_password_hash_base64,
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64,
+ AllowUploadDownload = var.allow_upload_download,
+ EnableCloudWatch = var.enable_cloudwatch,
+ NTPPrimary = var.primary_ntp,
+ NTPSecondary = var.secondary_ntp,
+ Shell = var.admin_shell,
+ EnableInstanceConnect = var.enable_instance_connect,
+ GatewayBootstrapScript = local.gateway_bootstrap_script64,
+ SICKey = local.gateway_SICkey_base64,
+ TokenA = var.memberAToken,
+ MemberAPublicAddress = var.allocate_and_associate_eip ? aws_eip.member_a_eip[0].public_ip : "",
+ AllocateAddress = var.allocate_and_associate_eip,
+ OsVersion = local.version_split
+ })
+}
+
+resource "aws_instance" "member-b-instance" {
+ depends_on = [
+ aws_network_interface.member_b_external_eni,
+ aws_network_interface.member_b_internal_eni
+ ]
+
+ launch_template {
+ id = aws_launch_template.member_b_launch_template.id
+ version = "$Latest"
+ }
+
+ disable_api_termination = var.disable_instance_termination
+
+ tags = merge({
+ Name = format("%s-Member-B",var.gateway_name),
+ x-chkp-member-ips = format("public-ip=%s:external-private-ip=%s:internal-private-ip=%s",
+ var.allocate_and_associate_eip ? aws_eip.member_b_eip[0].public_ip : "", aws_network_interface.member_b_external_eni.private_ip,aws_network_interface.member_b_internal_eni.private_ip),
+ x-chkp-cluster-ips = format("cluster-ip=%s:cluster-eth0-private-ip=%s:cluster-eth1-private-ip=%s",
+ aws_eip.cluster_eip.public_ip, element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0),
+ element(tolist(setsubtract(tolist(aws_network_interface.member_a_internal_eni.private_ips), [aws_network_interface.member_a_internal_eni.private_ip])), 0))
+ }, var.instance_tags)
+
+ ebs_block_device {
+ device_name = "/dev/xvda"
+ volume_type = "gp2"
+ volume_size = var.volume_size
+ encrypted = local.volume_encryption_condition
+ kms_key_id = local.volume_encryption_condition ? var.volume_encryption : ""
+ }
+
+ lifecycle {
+ ignore_changes = [ebs_block_device,]
+ }
+
+ user_data = templatefile("${path.module}/cluster_member_b_userdata.yaml", {
+ // script's arguments
+ Hostname = var.gateway_hostname,
+ PasswordHash = local.gateway_password_hash_base64,
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64,
+ AllowUploadDownload = var.allow_upload_download,
+ EnableCloudWatch = var.enable_cloudwatch,
+ NTPPrimary = var.primary_ntp,
+ NTPSecondary = var.secondary_ntp,
+ Shell = var.admin_shell,
+ EnableInstanceConnect = var.enable_instance_connect,
+ GatewayBootstrapScript = local.gateway_bootstrap_script64,
+ SICKey = local.gateway_SICkey_base64,
+ TokenB = var.memberBToken,
+ MemberBPublicAddress = var.allocate_and_associate_eip ? aws_eip.member_b_eip[0].public_ip : "",
+ AllocateAddress = var.allocate_and_associate_eip,
+ OsVersion = local.version_split
+ })
+}
+
+resource "aws_eip" "cluster_eip" {
+}
+
+resource "aws_eip" "member_a_eip" {
+ count = var.allocate_and_associate_eip ? 1 : 0
+}
+
+resource "aws_eip" "member_b_eip" {
+ count = var.allocate_and_associate_eip ? 1 : 0
+}
+
+resource "aws_eip_association" "cluster_address_assoc" {
+ depends_on = [aws_instance.member-a-instance]
+ allocation_id = aws_eip.cluster_eip.id
+ lifecycle {
+ ignore_changes = [
+ network_interface_id, private_ip_address
+ ]
+ }
+ network_interface_id = aws_network_interface.member_a_external_eni.id
+ private_ip_address = length(tolist(aws_network_interface.member_a_external_eni.private_ips)) > 1 ? element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0) : ""//extracting member's secondary ip which represent the cluster ip
+}
+resource "aws_eip_association" "member_a_address_assoc" {
+ depends_on = [aws_instance.member-a-instance]
+ count = var.allocate_and_associate_eip ? 1 : 0
+ allocation_id = aws_eip.member_a_eip[0].id
+ network_interface_id = aws_network_interface.member_a_external_eni.id
+ private_ip_address = aws_network_interface.member_a_external_eni.private_ip //primary
+}
+resource "aws_eip_association" "member_b_address_assoc" {
+ depends_on = [aws_instance.member-b-instance]
+ count = var.allocate_and_associate_eip ? 1 : 0
+ allocation_id = aws_eip.member_b_eip[0].id
+ network_interface_id = aws_network_interface.member_b_external_eni.id
+ private_ip_address = aws_network_interface.member_b_external_eni.private_ip //primary
+}
+
diff --git a/modules/cluster/output.tf b/modules/cluster/output.tf
new file mode 100755
index 0000000..6e8f5cb
--- /dev/null
+++ b/modules/cluster/output.tf
@@ -0,0 +1,24 @@
+output "ami_id" {
+ value = module.amis.ami_id
+}
+output "cluster_public_ip" {
+ value = aws_eip.cluster_eip.*.public_ip
+}
+output "member_a_public_ip" {
+ value = aws_eip.member_a_eip.*.public_ip
+}
+output "member_b_public_ip" {
+ value = aws_eip.member_b_eip.*.public_ip
+}
+output "member_a_ssh" {
+ value = var.allocate_and_associate_eip ? format("ssh -i %s admin@%s", var.key_name, aws_eip.member_a_eip[0].public_ip) : ""
+}
+output "member_b_ssh" {
+ value = var.allocate_and_associate_eip ? format("ssh -i %s admin@%s", var.key_name, aws_eip.member_b_eip[0].public_ip) : ""
+}
+output "member_a_url" {
+ value = var.allocate_and_associate_eip ? format("https://%s", aws_eip.member_a_eip[0].public_ip) : ""
+}
+output "member_b_url" {
+ value = var.allocate_and_associate_eip ? format("https://%s", aws_eip.member_b_eip[0].public_ip) : ""
+}
\ No newline at end of file
diff --git a/modules/cluster/variables.tf b/modules/cluster/variables.tf
new file mode 100755
index 0000000..ecbb78e
--- /dev/null
+++ b/modules/cluster/variables.tf
@@ -0,0 +1,175 @@
+// Module: Check Point CloudGuard Network Security Cluster into an existing VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "public_subnet_id" {
+ type = string
+ description = "The public subnet of the cluster. The cluster's public IPs will be generated from this subnet"
+}
+variable "private_subnet_id" {
+ type = string
+ description = "The private subnet of the cluster. The cluster's private IPs will be generated from this subnet"
+}
+variable "private_route_table" {
+ type = string
+ description = "(Optional) Set 0.0.0.0/0 route to the Active Cluster member instance in this route table (e.g. rtb-12a34567). Route table cannot have an existing 0.0.0.0/0 route"
+ default= ""
+}
+
+// --- EC2 Instance Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Cluster-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "allocate_and_associate_eip" {
+ type = bool
+ description = "If set to true, an elastic IP will be allocated and associated with each cluster member, in addition to the shared cluster Elastic IP"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instances"
+ default = {}
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the cluster profile"
+ default = ""
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Quick connect to Smart-1 Cloud (Recommended) ---
+variable "memberAToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Single AZ Cluster to Smart-1 Cloud."
+}
+variable "memberBToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Single AZ Cluster to Smart-1 Cloud."
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) Name tag prefix of the resources"
+ default = ""
+}
+variable "gateway_hostname" {
+ type = string
+ description = "(Optional) The host name will be appended with member-a/b accordingly"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/cluster/versions.tf b/modules/cluster/versions.tf
new file mode 100755
index 0000000..c138bbb
--- /dev/null
+++ b/modules/cluster/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
diff --git a/modules/cluster_iam_role/main.tf b/modules/cluster_iam_role/main.tf
new file mode 100755
index 0000000..b56eacd
--- /dev/null
+++ b/modules/cluster_iam_role/main.tf
@@ -0,0 +1,38 @@
+resource "aws_iam_role" "cluster_iam_role" {
+ assume_role_policy = data.aws_iam_policy_document.cluster_role_assume_policy_document.json
+ path = "/"
+}
+
+data "aws_iam_policy_document" "cluster_role_assume_policy_document" {
+ version = "2012-10-17"
+ statement {
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+ principals {
+ type = "Service"
+ identifiers = ["ec2.amazonaws.com"]
+ }
+ }
+}
+
+data "aws_iam_policy_document" "cluster_role_policy_doc" {
+ version = "2012-10-17"
+ statement {
+ effect = "Allow"
+ actions = [
+ "ec2:AssignPrivateIpAddresses",
+ "ec2:AssociateAddress",
+ "ec2:CreateRoute",
+ "ec2:DescribeNetworkInterfaces",
+ "ec2:DescribeRouteTables",
+ "ec2:ReplaceRoute"]
+ resources = ["*"]
+ }
+}
+resource "aws_iam_policy" "cluster_role_policy" {
+ policy = data.aws_iam_policy_document.cluster_role_policy_doc.json
+}
+resource "aws_iam_role_policy_attachment" "attach_policy" {
+ policy_arn = aws_iam_policy.cluster_role_policy.arn
+ role = aws_iam_role.cluster_iam_role.id
+}
\ No newline at end of file
diff --git a/modules/cluster_iam_role/output.tf b/modules/cluster_iam_role/output.tf
new file mode 100755
index 0000000..7bbf035
--- /dev/null
+++ b/modules/cluster_iam_role/output.tf
@@ -0,0 +1,9 @@
+output "cluster_iam_role" {
+ value = aws_iam_role.cluster_iam_role
+}
+output "cluster_iam_role_arn" {
+ value = aws_iam_role.cluster_iam_role.arn
+}
+output "cluster_iam_role_name" {
+ value = aws_iam_role.cluster_iam_role.name
+}
\ No newline at end of file
diff --git a/modules/cluster_master/README.md b/modules/cluster_master/README.md
new file mode 100755
index 0000000..99d7376
--- /dev/null
+++ b/modules/cluster_master/README.md
@@ -0,0 +1,158 @@
+# Check Point CloudGuard Network Security Cluster Master Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Cluster into a new VPC.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [VPC](https://www.terraform.io/docs/providers/aws/r/vpc.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html) - conditional creation
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Deploying a Check Point Cluster in AWS (Amazon Web Services)](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk104418) for additional information
+
+This solution uses the following modules:
+- cluster
+- amis
+- vpc
+- cluster_iam_role
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Instead of the standard terraform apply command, use the following:**
+```
+ terraform apply -target=module.{module_name}.aws_route_table.private_subnet_rtb -auto-approve && terraform apply
+ ```
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/cluster_master"
+ version = "1.0.2"
+
+
+ // --- VPC Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ }
+ private_subnets_map = {
+ "us-east-1a" = 2
+ }
+ subnets_bit_length = 8
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Cluster-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+ predefined_role = ""
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ memberAToken = ""
+ memberBToken = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+ }
+```
+
+- Conditional creation
+ - To create an Elastic IP and associate it to each cluster member instance:
+ ```
+ allocate_and_associate_eip = "true"
+ ```
+ - To create IAM Role:
+ ```
+ predefined_role = ""
+ ```
+
+ ### Optional re-deploy of cluster member:
+ In case of re-deploying one cluster member, make sure that it's in STANDBY state, and the second member is the ACTIVE one.
+ Follow the commands below in order to re-deploy (replace MEMBER with a or b):
+ - terraform taint module.launch_cluster_into_vpc.aws_instance.member-MEMBER-instance
+ - terraform plan (review the changes)
+ - terraform apply
+ - In Smart Console: reset SIC with the re-deployed member and install policy
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|----------------------------|--------------|---------------------------------------------------------------------------------------------------------------|
+| vpc_cidr | The CIDR block of the VPC | string | |
+| public_subnets_map | A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair (e.g., {"us-east-1a" = 1}). | map | |
+| private_subnets_map | A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair (e.g., {"us-east-1a" = 2}). | map | |
+| subnets_bit_length | Number of additional bits to extend the VPC CIDR. For example, with a VPC CIDR ending in /16 and subnets_bit_length = 4, resulting subnet will have length /20. | number | |
+| gateway_name | (Optional) The name tag of the Security Gateway instances | string | **Default:** Check-Point-Cluster-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | |
+| allocate_and_associate_eip | Allocate and associate Elastic IP for each cluster member, in addition to the shared cluster Elastic IP. | bool | true/false
**Default:** true |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| volume_encryption | KMS or CMK key Identifier. Use key ID, alias, or ARN (e.g., alias/aws/ebs). | string | **Default:** alias/aws/ebs |
+| enable_instance_connect | Enable AWS Instance Connect. Supporting regions are listed [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/). | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevent accidental termination. Note: When set, `terraform destroy` may not work properly. | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Deploy the instance with metadata v2 token requirement | bool | true/false
**Default:** true |
+| instance_tags | (Optional) A map of tags (key=value) to add to Gateway EC2 Instances | map(string) | **Default:** {} |
+| predefined_role | (Optional) Predefined IAM role to attach to the cluster profile | string | |
+| gateway_version | Gateway version and license | string | R81.10-BYOL, R81.20-BYOL, R82-BYOL, etc.
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced CLI configuration | string | /etc/cli.sh, /bin/bash, /bin/csh, /bin/tcsh
**Default:** /etc/cli.sh |
+| gateway_SICKey | Secure Internal Communication key for trusted connection (at least 8 alphanumeric characters) | string | **Default:** "12345678" |
+| gateway_password_hash | (Optional) Admin user's password hash (use `openssl passwd -6 PASSWORD`). | string | |
+| memberAToken | (Optional) Quick connect token for Smart-1 Cloud, for Member A. | string | |
+| memberBToken | (Optional) Quick connect token for Smart-1 Cloud, for Member B. | string | |
+| resources_tag_name | (Optional) Prefix for resource tags | string | |
+| gateway_hostname | (Optional) Hostname of the gateway (appended with member-a/b). | string | |
+| allow_upload_download | Automatically download Blade Contracts and other important data. | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point-specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Commands to run on the initial boot, separated by semicolons (;). | string | |
+| primary_ntp | (Optional) IPv4 address of the primary Network Time Protocol (NTP) server | string | **Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) IPv4 address of the secondary Network Time Protocol (NTP) server | string | **Default:** 0.pool.ntp.org |
+| gateway_maintenance_mode_password_hash | (Optional) Maintenance-mode password hash (use `grub2-mkpasswd-pbkdf2` for hash generation). | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------|-----------------------------------------------------|
+| ami_id | The ami id of the deployed Security Cluster members |
+| cluster_public_ip | The public address of the cluster |
+| member_a_public_ip | The public address of member A |
+| member_b_public_ip | The public address of member B |
+| member_a_ssh | SSH command to member A |
+| member_b_ssh | SSH command to member B |
+| member_a_url | URL to the member A portal |
+| member_b_url | URL to the member B portal |
diff --git a/modules/cluster_master/locals.tf b/modules/cluster_master/locals.tf
new file mode 100755
index 0000000..b77484f
--- /dev/null
+++ b/modules/cluster_master/locals.tf
@@ -0,0 +1,52 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ create_iam_role = var.predefined_role == "" ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ is_both_tokens_used = length(var.memberAToken) > 0 == length(var.memberBToken) > 0
+ validation_message_both = "Smart-1 Cloud Tokens for member A and member B can not be empty."
+ //Will fail if var.memberAToken is empty and var.memberBToken isn't and vice versa
+ regex_s1c_validate = regex("^$", (local.is_both_tokens_used ? "" : local.validation_message_both))
+
+ is_tokens_used = length(var.memberAToken) > 0
+ is_both_tokens_the_same = var.memberAToken == var.memberBToken
+ validation_message_unique = "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
+ //Will fail if both s1c tokens are the same
+ regex_s1c_unique = local.is_tokens_used ? regex("^$", (local.is_both_tokens_the_same ? local.validation_message_unique : "")) : ""
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.gateway_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.gateway_hostname) == var.gateway_hostname ? 0 : "Variable [gateway_hostname] must be a valid hostname label or an empty string"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+}
diff --git a/modules/cluster_master/main.tf b/modules/cluster_master/main.tf
new file mode 100755
index 0000000..42fe087
--- /dev/null
+++ b/modules/cluster_master/main.tf
@@ -0,0 +1,58 @@
+
+// --- VPC ---
+module "launch_vpc" {
+ source = "../vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = var.private_subnets_map
+ subnets_bit_length = var.subnets_bit_length
+}
+
+resource "aws_route_table" "private_subnet_rtb" {
+ depends_on = [module.launch_vpc]
+ vpc_id = module.launch_vpc.vpc_id
+ tags = {
+ Name = "Private Subnets Route Table"
+ }
+}
+resource "aws_route_table_association" "private_rtb_to_private_subnets" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ route_table_id = aws_route_table.private_subnet_rtb.id
+ subnet_id = module.launch_vpc.private_subnets_ids_list[0]
+}
+module "launch_cluster_into_vpc" {
+ source = "../cluster"
+
+
+ vpc_id = module.launch_vpc.vpc_id
+ public_subnet_id = module.launch_vpc.public_subnets_ids_list[0]
+ private_subnet_id = module.launch_vpc.private_subnets_ids_list[0]
+ security_rules = var.security_rules
+ private_route_table = aws_route_table.private_subnet_rtb.id
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ allocate_and_associate_eip = var.allocate_and_associate_eip
+ volume_size = var.volume_size
+ volume_encryption = var.volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ instance_tags = var.instance_tags
+ predefined_role = var.predefined_role
+ gateway_version = var.gateway_version
+ admin_shell = var.admin_shell
+ gateway_SICKey = var.gateway_SICKey
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ memberAToken = var.memberAToken
+ memberBToken = var.memberBToken
+ resources_tag_name = var.resources_tag_name
+ gateway_hostname = var.gateway_hostname
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = var.gateway_bootstrap_script
+ primary_ntp = var.primary_ntp
+ secondary_ntp = var.secondary_ntp
+}
diff --git a/modules/cluster_master/output.tf b/modules/cluster_master/output.tf
new file mode 100755
index 0000000..c1f4738
--- /dev/null
+++ b/modules/cluster_master/output.tf
@@ -0,0 +1,24 @@
+output "ami_id" {
+ value = module.launch_cluster_into_vpc.ami_id
+}
+output "cluster_public_ip" {
+ value = module.launch_cluster_into_vpc.cluster_public_ip
+}
+output "member_a_public_ip" {
+ value = module.launch_cluster_into_vpc.member_a_public_ip
+}
+output "member_b_public_ip" {
+ value = module.launch_cluster_into_vpc.member_b_public_ip
+}
+output "member_a_ssh" {
+ value = module.launch_cluster_into_vpc.member_a_ssh
+}
+output "member_b_ssh" {
+ value = module.launch_cluster_into_vpc.member_b_ssh
+}
+output "member_a_url" {
+ value = module.launch_cluster_into_vpc.member_a_url
+}
+output "member_b_url" {
+ value = module.launch_cluster_into_vpc.member_b_url
+}
\ No newline at end of file
diff --git a/modules/cluster_master/variables.tf b/modules/cluster_master/variables.tf
new file mode 100755
index 0000000..876e149
--- /dev/null
+++ b/modules/cluster_master/variables.tf
@@ -0,0 +1,177 @@
+// Module: Check Point CloudGuard Network Security Cluster into a new VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pairs. (e.g. {\"us-east-1a\" = 1} ) "
+}
+variable "private_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pairs. (e.g. {\"us-east-1a\" = 2} ) "
+
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+
+// --- EC2 Instance Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Cluster-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "allocate_and_associate_eip" {
+ type = bool
+ description = "If set to true, an elastic IP will be allocated and associated with each cluster member, in addition to the shared cluster Elastic IP"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instance"
+ default = {}
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the cluster profile"
+ default = ""
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Quick connect to Smart-1 Cloud (Recommended) ---
+variable "memberAToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Single AZ Cluster to Smart-1 Cloud."
+}
+variable "memberBToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Single AZ Cluster to Smart-1 Cloud."
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) Name tag prefix of the resources"
+ default = ""
+}
+variable "gateway_hostname" {
+ type = string
+ description = "(Optional) The host name will be appended with member-a/b accordingly"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/cluster_master/versions.tf b/modules/cluster_master/versions.tf
new file mode 100755
index 0000000..c138bbb
--- /dev/null
+++ b/modules/cluster_master/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
diff --git a/modules/cme_iam_role/README.md b/modules/cme_iam_role/README.md
index ebb899b..f859d26 100755
--- a/modules/cme_iam_role/README.md
+++ b/modules/cme_iam_role/README.md
@@ -16,6 +16,20 @@ See the [Creating an AWS IAM Role for Security Management Server](https://suppor
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/cme_iam_role"
+ version = "1.0.2"
+
+ permissions = "Create with read permissions"
+ sts_roles = ['arn:aws:iam::111111111111:role/role_name']
+ trusted_account = ""
+}
+```
## Inputs
| Name | Description | Type | Allowed Values |
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -25,6 +39,12 @@ Follow best practices for using CGNS modules on [the root page](https://registry
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|----------------------|---------------------------------------|
| cme_iam_role_arn | The created AWS IAM Role arn |
diff --git a/modules/cme_iam_role_gwlb/README.md b/modules/cme_iam_role_gwlb/README.md
index 1313e2b..23e0fe9 100755
--- a/modules/cme_iam_role_gwlb/README.md
+++ b/modules/cme_iam_role_gwlb/README.md
@@ -16,8 +16,23 @@ See the [Creating an AWS IAM Role for Security Management Server](https://suppor
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/cme_iam_role_gwlb"
+ version = "1.0.2"
+
+ permissions = "Create with read permissions"
+ sts_roles = ['arn:aws:iam::111111111111:role/role_name']
+ trusted_account = ""
+}
+```
## Inputs
+
| Name | Description | Type | Allowed Values |
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| permissions | The IAM role permissions | string | - Create with assume role permissions (specify an STS role ARN)
- Create with read permissions
- Create with read-write permissions
**Default:** Create with read permissions |
@@ -26,6 +41,12 @@ Follow best practices for using CGNS modules on [the root page](https://registry
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|----------------------|---------------------------------------|
| cme_iam_role_arn | The created AWS IAM Role arn |
diff --git a/modules/common/gateway_instance/gateway_userdata.yaml b/modules/common/gateway_instance/gateway_userdata.yaml
deleted file mode 100755
index ba55e02..0000000
--- a/modules/common/gateway_instance/gateway_userdata.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-#cloud-config
-runcmd:
- - |
- python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" "smart1CloudToken=\"${TokenKey}\"" installationType=\"gateway\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"20240704\" templateName=\"gateway\" templateType=\"terraform\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${GatewayBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/cross_az_cluster/README.md b/modules/cross_az_cluster/README.md
new file mode 100755
index 0000000..58249a1
--- /dev/null
+++ b/modules/cross_az_cluster/README.md
@@ -0,0 +1,147 @@
+# Check Point CloudGuard Network Security Cross AZ Cluster Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Cross AZ Cluster into an existing VPC on AWS.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html)
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html) - conditional creation
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Deploying a Check Point Cluster in AWS (Amazon Web Services)](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_for_AWS_Cross_AZ_Cluster/Default.htm) for additional information
+
+This solution uses the following modules:
+- amis
+- cluster_iam_role
+
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/cross_az_cluster"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ public_subnet_ids = ["subnet-abc123", "subnet-def456"]
+ private_subnet_ids = ["subnet-abc234", "subnet-def567"]
+ private_route_table = "rtb-12345678"
+
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Cluster-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+ predefined_role = ""
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ memberAToken = ""
+ memberBToken = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+}
+ ```
+
+- Conditional creation
+ - To create IAM Role:
+ ```
+ predefined_role = ""
+ ```
+ - To create route from '0.0.0.0/0' to the Active Cluster member instance, please provide route table:
+ ```
+ private_route_table = "rtb-12345678"
+ ```
+
+ ### Optional re-deploy of cluster member:
+ In case of re-deploying one cluster member, make sure that it's in STANDBY state, and the second member is the ACTIVE one.
+ Follow the commands below in order to re-deploy (replace MEMBER with a or b):
+ - terraform taint aws_instance.member-MEMBER-instance
+ - terraform plan (review the changes)
+ - terraform apply
+ - In Smart Console: reset SIC with the re-deployed member and install policy
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------------|
+| vpc_id | The VPC id in which to deploy | string | |
+| public_subnet_ids | List of public subnet IDs to launch resources into. At least 2 | list(string) | |
+| private_subnet_ids | List of private subnet IDs to launch resources into. At least 2 | list(string) | |
+| private_route_table | (Optional) Set 0.0.0.0/0 route to the Active Cluster member instance in this route table. Route table cannot have an existing 0.0.0.0/0 route | string | |
+| gateway_name | (Optional) The name tag of the Security Gateway instances | string | **Default:** Check-Point-Cluster-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| volume_encryption | KMS or CMK key Identifier: Use key ID, alias, or ARN. Key alias should be prefixed with 'alias/'. | string | **Default:** alias/aws/ebs |
+| enable_instance_connect | Enable AWS Instance Connect. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents an instance from accidental termination. Note: Once this attribute is true terraform destroy won't work properly | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| instance_tags | (Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instances | map(string) | |
+| predefined_role | (Optional) A predefined IAM role to attach to the cluster profile | string | |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components. At least 8 alphanumeric characters required | string | |
+| gateway_password_hash | (Optional) Admin user's password hash | string | |
+| memberAToken | (Recommended) Quick connect to Smart-1 Cloud. Follow SK180501 for instructions. | string | |
+| memberBToken | (Recommended) Quick connect to Smart-1 Cloud. Follow SK180501 for instructions. | string | |
+| resources_tag_name | (Optional) Name tag prefix of the resources | string | |
+| gateway_hostname | (Optional) The host name will be appended with member-a/b accordingly. The name must not contain reserved words. Refer to SK40179. | string | |
+| allow_upload_download | Automatically download Blade Contracts and other important data | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | |
+| primary_ntp | (Optional) The IPv4 addresses of Network Time Protocol primary server | string | **Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) The IPv4 addresses of Network Time Protocol secondary server | string | **Default:** 0.pool.ntp.org |
+| gateway_maintenance_mode_password_hash | (Optional) Check Point recommends setting Admin user's password and maintenance-mode password. | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------|--------------------------------------------------------------|
+| ami_id | The ami id of the deployed Security Cross AZ Cluster members |
+| cluster_public_ip | The public address of the cluster |
+| member_a_public_ip | The public address of member A |
+| member_b_public_ip | The public address of member B |
+| member_a_ssh | SSH command to member A |
+| member_b_ssh | SSH command to member B |
+| member_a_url | URL to the member A portal |
+| member_b_url | URL to the member B portal |
diff --git a/modules/cross_az_cluster/cluster_member_a_userdata.yaml b/modules/cross_az_cluster/cluster_member_a_userdata.yaml
new file mode 100755
index 0000000..9adae39
--- /dev/null
+++ b/modules/cross_az_cluster/cluster_member_a_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" "smart1CloudToken=\"${TokenA}\"" installationType=\"cross-az-cluster\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"cross_az_cluster\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname}\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" elasticIp=\"${MemberAPublicAddress}\" otherMemberIp=\"${MemberBPrivateAddressCluster}\" clusterIp=\"${PublicAddressCluster}\" secondaryIp=\"${MemberAPrivateAddressSecondary}\" otherMemberPrivateClusterIp=\"${MemberBPrivateAddressSecondary}\" bootstrapScript64=\"${GatewayBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/cross_az_cluster/cluster_member_b_userdata.yaml b/modules/cross_az_cluster/cluster_member_b_userdata.yaml
new file mode 100755
index 0000000..2c59f32
--- /dev/null
+++ b/modules/cross_az_cluster/cluster_member_b_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" "smart1CloudToken=\"${TokenB}\"" installationType=\"cross-az-cluster\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"cross_az_cluster\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname}\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" elasticIp=\"${MemberBPublicAddress}\" otherMemberIp=\"${MemberAPrivateAddressCluster}\" clusterIp=\"${PublicAddressCluster}\" secondaryIp=\"${MemberBPrivateAddressSecondary}\" otherMemberPrivateClusterIp=\"${MemberAPrivateAddressSecondary}\" bootstrapScript64=\"${GatewayBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/cross_az_cluster/locals.tf b/modules/cross_az_cluster/locals.tf
new file mode 100755
index 0000000..19f67f3
--- /dev/null
+++ b/modules/cross_az_cluster/locals.tf
@@ -0,0 +1,75 @@
+locals {
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ enable_cloudwatch_policy = var.enable_cloudwatch ? 1 : 0
+ create_iam_role = var.predefined_role == "" ? 1 : 0
+ provided_roue_table = var.private_route_table == "" ? 0 : 1
+ internal_route_table_condition = var.private_route_table != "" ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ regex_token_valid = "(^https://(.+).checkpoint.com/app/maas/api/v1/tenant(.+)|^$)"
+ //TokenA: will fail if decode token should contain https:// and .checkpoint.com/app/maas/api/v1/tenant or empty string
+ split_tokenA = split(" ", var.memberAToken)
+ tokenA_decode = base64decode(element(local.split_tokenA, length(local.split_tokenA)-1))
+ regex_tokenA = regex(local.regex_token_valid, local.tokenA_decode) == local.tokenA_decode ? 0 : "Smart-1 Cloud token A is invalid format"
+
+ //TokenB: will fail if decode token should contain https:// and .checkpoint.com/app/maas/api/v1/tenant or empty string
+ split_tokenB = split(" ", var.memberBToken)
+ tokenB_decode = base64decode(element(local.split_tokenB, length(local.split_tokenB)-1))
+ regex_tokenB = regex(local.regex_token_valid, local.tokenB_decode) == local.tokenB_decode ? 0 : "Smart-1 Cloud token B is invalid format"
+
+ is_both_tokens_used = length(var.memberAToken) > 0 == length(var.memberBToken) > 0
+ validation_message_both = "Smart-1 Cloud Tokens for member A and member B can not be empty."
+ //Will fail if var.memberAToken is empty and var.memberBToken isn't and vice versa
+ regex_s1c_validate = regex("^$", (local.is_both_tokens_used ? "" : local.validation_message_both))
+
+ is_tokens_used = length(var.memberAToken) > 0
+ is_both_tokens_the_same = var.memberAToken == var.memberBToken
+ validation_message_unique = "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
+ //Will fail if both s1c tokens are the same
+ regex_s1c_unique = local.is_tokens_used ? regex("^$", (local.is_both_tokens_the_same ? local.validation_message_unique : "")) : ""
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.gateway_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.gateway_hostname) == var.gateway_hostname ? 0 : "Variable [gateway_hostname] must be a valid hostname label or an empty string"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ gateway_bootstrap_script64 = base64encode(var.gateway_bootstrap_script)
+ gateway_SICkey_base64=base64encode(var.gateway_SICKey)
+ gateway_password_hash_base64=base64encode(var.gateway_password_hash)
+ maintenance_mode_password_hash_base64 = base64encode(var.gateway_maintenance_mode_password_hash)
+
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.gateway_version), 0)
+ volume_type_allowed_values = [
+ "gp3",
+ "gp2"]
+ // will fail if [var.VolumeType] is invalid:
+ validate_volume_type = index(local.volume_type_allowed_values, var.volume_type)
+}
diff --git a/modules/cross_az_cluster/main.tf b/modules/cross_az_cluster/main.tf
new file mode 100755
index 0000000..a0aa922
--- /dev/null
+++ b/modules/cross_az_cluster/main.tf
@@ -0,0 +1,288 @@
+module "amis" {
+ source = "../amis"
+
+ version_license = var.gateway_version
+ chkp_type = "gateway"
+}
+
+module "common_permissive_sg" {
+ source = "../permissive_sg"
+ security_rules = var.security_rules
+ vpc_id = var.vpc_id
+ resources_tag_name = var.resources_tag_name
+ gateway_name = var.gateway_name
+}
+
+resource "aws_iam_instance_profile" "cluster_instance_profile" {
+ path = "/"
+ role = local.create_iam_role == 1 ? join("", module.cluster_iam_role.*.cluster_iam_role_name) : var.predefined_role
+}
+
+module "cluster_iam_role" {
+ source = "../cluster_iam_role"
+ count = local.create_iam_role
+}
+
+module "attach_cloudwatch_policy" {
+ source = "../cloudwatch_policy"
+ count = local.enable_cloudwatch_policy
+ role = aws_iam_instance_profile.cluster_instance_profile.role
+ tag_name = var.resources_tag_name != "" ? var.resources_tag_name : var.gateway_name
+}
+
+resource "aws_network_interface" "member_a_external_eni" {
+ subnet_id = var.public_subnet_ids[0]
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member A external"
+ source_dest_check = false
+ private_ips_count = 1
+ tags = {
+ x-chkp-interface-type = "external" }
+}
+
+resource "aws_network_interface" "member_b_external_eni" {
+ subnet_id = var.public_subnet_ids[1]
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member B external"
+ source_dest_check = false
+ private_ips_count = 1
+ tags = {
+ x-chkp-interface-type = "external" }
+}
+
+resource "aws_network_interface" "member_a_internal_eni" {
+ subnet_id = var.private_subnet_ids[0]
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member A internal"
+ source_dest_check = false
+ tags = {
+ x-chkp-interface-type = "internal" }
+}
+
+resource "aws_network_interface" "member_b_internal_eni" {
+ subnet_id = var.private_subnet_ids[1]
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "Member B internal"
+ source_dest_check = false
+ tags = {
+ x-chkp-interface-type = "internal" }
+}
+
+resource "aws_route" "internal_default_route" {
+ count = local.internal_route_table_condition
+ route_table_id = var.private_route_table
+ lifecycle {
+ ignore_changes = [network_interface_id,]
+ }
+ destination_cidr_block = "0.0.0.0/0"
+ network_interface_id = aws_network_interface.member_a_internal_eni.id
+}
+
+resource "aws_route_table_association" "private_rtb_a" {
+ count = var.private_route_table == "" ? 0 : 1
+ route_table_id = var.private_route_table
+ subnet_id = var.private_subnet_ids[0]
+}
+resource "aws_route_table_association" "private_rtb_b" {
+ count = var.private_route_table == "" ? 0 : 1
+ route_table_id = var.private_route_table
+ subnet_id = var.private_subnet_ids[1]
+}
+
+resource "aws_launch_template" "member_a_launch_template" {
+ depends_on = [
+ aws_network_interface.member_a_external_eni,
+ aws_network_interface.member_a_internal_eni
+ ]
+ instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ image_id = module.amis.ami_id
+ description = "Initial launch template version"
+
+ iam_instance_profile {
+ name = aws_iam_instance_profile.cluster_instance_profile.id
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_a_external_eni.id
+ device_index = 0
+ }
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_a_internal_eni.id
+ device_index = 1
+ }
+}
+
+resource "aws_launch_template" "member_b_launch_template" {
+ depends_on = [
+ aws_network_interface.member_b_external_eni,
+ aws_network_interface.member_b_internal_eni
+ ]
+ instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ image_id = module.amis.ami_id
+ description = "Initial launch template version"
+
+ iam_instance_profile {
+ name = aws_iam_instance_profile.cluster_instance_profile.id
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_b_external_eni.id
+ device_index = 0
+ }
+ network_interfaces {
+ network_interface_id = aws_network_interface.member_b_internal_eni.id
+ device_index = 1
+ }
+}
+
+resource "aws_instance" "member-a-instance" {
+ depends_on = [
+ aws_launch_template.member_a_launch_template
+ ]
+
+ launch_template {
+ id = aws_launch_template.member_a_launch_template.id
+ version = "$Latest"
+ }
+
+ disable_api_termination = var.disable_instance_termination
+
+ tags = merge({
+ Name = format("%s-Member-A",var.gateway_name),
+ x-chkp-member-ips = format("public-ip=%s:external-private-ip=%s:internal-private-ip=%s",
+ aws_eip.member_a_eip.public_ip, aws_network_interface.member_a_external_eni.private_ip,aws_network_interface.member_a_internal_eni.private_ip),
+ x-chkp-cluster-ips = format("cluster-ip=%s:secondary-external-private-ip=%s",
+ aws_eip.cluster_eip.public_ip, element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0))
+ }, var.instance_tags)
+
+ ebs_block_device {
+ device_name = "/dev/xvda"
+ volume_type = "gp2"
+ volume_size = var.volume_size
+ encrypted = local.volume_encryption_condition
+ kms_key_id = local.volume_encryption_condition ? var.volume_encryption : ""
+ }
+
+ lifecycle {
+ ignore_changes = [ebs_block_device,]
+ }
+
+ user_data = templatefile("${path.module}/cluster_member_a_userdata.yaml", {
+ // script's arguments
+ Hostname = var.gateway_hostname,
+ PasswordHash = local.gateway_password_hash_base64,
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64
+ AllowUploadDownload = var.allow_upload_download,
+ EnableCloudWatch = var.enable_cloudwatch,
+ NTPPrimary = var.primary_ntp,
+ NTPSecondary = var.secondary_ntp,
+ Shell = var.admin_shell,
+ EnableInstanceConnect = var.enable_instance_connect,
+ GatewayBootstrapScript = local.gateway_bootstrap_script64,
+ SICKey = local.gateway_SICkey_base64,
+ TokenA = var.memberAToken,
+ MemberAPublicAddress = aws_eip.member_a_eip.public_ip,
+ PublicAddressCluster = aws_eip.cluster_eip.public_ip,
+ MemberAPrivateAddressSecondary = length(tolist(aws_network_interface.member_a_external_eni.private_ips)) > 1 ? element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0) : "",//extracting member's secondary ip which represent the cluster ip
+ MemberBPrivateAddressCluster = aws_network_interface.member_b_internal_eni.private_ip,
+ MemberBPrivateAddressSecondary = length(tolist(aws_network_interface.member_b_external_eni.private_ips)) > 1 ? element(tolist(setsubtract(tolist(aws_network_interface.member_b_external_eni.private_ips), [aws_network_interface.member_b_external_eni.private_ip])), 0) : "",
+ AllocateAddress = true,
+ OsVersion = local.version_split
+ })
+}
+
+resource "aws_instance" "member-b-instance" {
+ depends_on = [
+ aws_launch_template.member_b_launch_template
+ ]
+
+ launch_template {
+ id = aws_launch_template.member_b_launch_template.id
+ version = "$Latest"
+ }
+
+ disable_api_termination = var.disable_instance_termination
+
+ tags = merge({
+ Name = format("%s-Member-B",var.gateway_name),
+ x-chkp-member-ips = format("public-ip=%s:external-private-ip=%s:internal-private-ip=%s",
+ aws_eip.member_b_eip.public_ip, aws_network_interface.member_b_external_eni.private_ip,aws_network_interface.member_b_internal_eni.private_ip),
+ x-chkp-cluster-ips = format("cluster-ip=%s:secondary-external-private-ip=%s",
+ aws_eip.cluster_eip.public_ip, element(tolist(setsubtract(tolist(aws_network_interface.member_b_external_eni.private_ips), [aws_network_interface.member_b_external_eni.private_ip])), 0))
+ }, var.instance_tags)
+
+ ebs_block_device {
+ device_name = "/dev/xvda"
+ volume_type = "gp2"
+ volume_size = var.volume_size
+ encrypted = local.volume_encryption_condition
+ kms_key_id = local.volume_encryption_condition ? var.volume_encryption : ""
+ }
+ lifecycle {
+ ignore_changes = [ebs_block_device,]
+ }
+
+ user_data = templatefile("${path.module}/cluster_member_b_userdata.yaml", {
+ // script's arguments
+ Hostname = var.gateway_hostname,
+ PasswordHash = local.gateway_password_hash_base64,
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64
+ AllowUploadDownload = var.allow_upload_download,
+ EnableCloudWatch = var.enable_cloudwatch,
+ NTPPrimary = var.primary_ntp,
+ NTPSecondary = var.secondary_ntp,
+ Shell = var.admin_shell,
+ EnableInstanceConnect = var.enable_instance_connect,
+ GatewayBootstrapScript = local.gateway_bootstrap_script64,
+ SICKey = local.gateway_SICkey_base64,
+ TokenB = var.memberBToken,
+ MemberBPublicAddress = aws_eip.member_b_eip.public_ip,
+ PublicAddressCluster=aws_eip.cluster_eip.public_ip,
+ MemberBPrivateAddressSecondary = length(tolist(aws_network_interface.member_b_external_eni.private_ips)) > 1 ? element(tolist(setsubtract(tolist(aws_network_interface.member_b_external_eni.private_ips), [aws_network_interface.member_b_external_eni.private_ip])), 0) : "", //extracting member's secondary ip which represent the member ip
+ MemberAPrivateAddressCluster=aws_network_interface.member_a_internal_eni.private_ip,
+ MemberAPrivateAddressSecondary = length(tolist(aws_network_interface.member_a_external_eni.private_ips)) > 1 ? element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0) : "",
+ AllocateAddress = true,
+ OsVersion = local.version_split
+ })
+}
+
+resource "aws_eip" "cluster_eip" {
+}
+resource "aws_eip" "member_a_eip" {
+}
+resource "aws_eip" "member_b_eip" {
+}
+
+resource "aws_eip_association" "cluster_address_assoc" {
+ depends_on = [aws_instance.member-a-instance]
+ allocation_id = aws_eip.cluster_eip.id
+ lifecycle {
+ ignore_changes = [
+ network_interface_id, private_ip_address
+ ]
+ }
+ network_interface_id = aws_network_interface.member_a_external_eni.id
+ private_ip_address = length(tolist(aws_network_interface.member_a_external_eni.private_ips)) > 1 ? element(tolist(setsubtract(tolist(aws_network_interface.member_a_external_eni.private_ips), [aws_network_interface.member_a_external_eni.private_ip])), 0) : ""//extracting member's secondary ip which represent the cluster ip
+}
+resource "aws_eip_association" "member_a_address_assoc" {
+ depends_on = [aws_instance.member-a-instance]
+ allocation_id = aws_eip.member_a_eip.id
+ network_interface_id = aws_network_interface.member_a_external_eni.id
+ private_ip_address = aws_network_interface.member_a_external_eni.private_ip //primary
+}
+resource "aws_eip_association" "member_b_address_assoc" {
+ depends_on = [aws_instance.member-b-instance]
+ allocation_id = aws_eip.member_b_eip.id
+ network_interface_id = aws_network_interface.member_b_external_eni.id
+ private_ip_address = aws_network_interface.member_b_external_eni.private_ip //primary
+}
\ No newline at end of file
diff --git a/modules/cross_az_cluster/output.tf b/modules/cross_az_cluster/output.tf
new file mode 100755
index 0000000..e475a65
--- /dev/null
+++ b/modules/cross_az_cluster/output.tf
@@ -0,0 +1,30 @@
+output "ami_id" {
+ value = module.amis.ami_id
+}
+output "cluster_public_ip" {
+ value = aws_eip.cluster_eip.*.public_ip
+}
+output "member_a_public_ip" {
+ value = aws_eip.member_a_eip.*.public_ip
+}
+output "member_b_public_ip" {
+ value = aws_eip.member_b_eip.*.public_ip
+}
+output "member_a_eni" {
+ value = aws_network_interface.member_a_external_eni.id
+}
+output "member_a_ssh" {
+ value = format("ssh -i %s admin@%s", var.key_name, aws_eip.member_a_eip.public_ip)
+}
+output "member_b_ssh" {
+ value = format("ssh -i %s admin@%s", var.key_name, aws_eip.member_b_eip.public_ip)
+}
+output "member_a_url" {
+ value = format("https://%s", aws_eip.member_a_eip.public_ip)
+}
+output "member_b_url" {
+ value = format("https://%s", aws_eip.member_b_eip.public_ip)
+}
+output "member_b_eni" {
+ value = aws_network_interface.member_b_external_eni.id
+}
\ No newline at end of file
diff --git a/modules/cross_az_cluster/variables.tf b/modules/cross_az_cluster/variables.tf
new file mode 100755
index 0000000..429e47f
--- /dev/null
+++ b/modules/cross_az_cluster/variables.tf
@@ -0,0 +1,175 @@
+// Module: Check Point CloudGuard Network Security Cross AZ Cluster into an existing VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "public_subnet_ids" {
+ type = list(string)
+ description = "List of public subnet IDs to launch resources into. At least 2"
+}
+variable "private_subnet_ids" {
+ type = list(string)
+ description = "List of public subnet IDs to launch resources into. At least 2"
+}
+variable "private_route_table" {
+ type = string
+ description = "(Optional) Set 0.0.0.0/0 route to the Active Cluster member instance in this route table (e.g. rtb-12a34567). Route table cannot have an existing 0.0.0.0/0 route"
+ default= ""
+}
+
+// --- EC2 Instance Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Cluster-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_type" {
+ type = string
+ description = "General Purpose SSD Volume Type"
+ default = "gp3"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instances"
+ default = {}
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the cluster profile"
+ default = ""
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Quick connect to Smart-1 Cloud (Recommended) ---
+variable "memberAToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+variable "memberBToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) Name tag prefix of the resources"
+ default = ""
+}
+variable "gateway_hostname" {
+ type = string
+ description = "(Optional) The host name will be appended with member-a/b accordingly"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/cross_az_cluster/versions.tf b/modules/cross_az_cluster/versions.tf
new file mode 100755
index 0000000..c138bbb
--- /dev/null
+++ b/modules/cross_az_cluster/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
diff --git a/modules/cross_az_cluster_master/README.md b/modules/cross_az_cluster_master/README.md
new file mode 100755
index 0000000..365e076
--- /dev/null
+++ b/modules/cross_az_cluster_master/README.md
@@ -0,0 +1,156 @@
+# Check Point CloudGuard Network Security Cross AZ Cluster Master Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Cross AZ Cluster into into a new VPC.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [VPC](https://www.terraform.io/docs/providers/aws/r/vpc.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Deploying a Check Point Cluster in AWS (Amazon Web Services)](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_for_AWS_Cross_AZ_Cluster/Default.htm) for additional information
+
+This solution uses the following modules:
+- cross_az_cluster
+- amis
+- vpc
+- cluster_iam_role
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Instead of the standard terraform apply command, use the following:**
+```
+ terraform apply -target=module.{module_name}.aws_route_table.private_subnet_rtb -auto-approve && terraform apply
+ ```
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/cross_az_cluster_master"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ "us-east-1b" = 2
+ }
+ private_subnets_map = {
+ "us-east-1a" = 3
+ "us-east-1b" = 4
+ }
+ subnets_bit_length = 8
+
+
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Cluster-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+ predefined_role = ""
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ memberAToken = ""
+ memberBToken = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+}
+ ```
+
+- Conditional creation
+ - To create IAM Role:
+ ```
+ predefined_role = ""
+ ```
+
+ ### Optional re-deploy of cluster member:
+ In case of re-deploying one cluster member, make sure that it's in STANDBY state, and the second member is the ACTIVE one.
+ Follow the commands below in order to re-deploy (replace MEMBER with a or b):
+ - terraform taint module.launch_cluster_into_vpc.aws_instance.member-MEMBER-instance
+ - terraform plan (review the changes)
+ - terraform apply
+ - In Smart Console: reset SIC with the re-deployed member and install policy
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------|
+| vpc_cidr | The CIDR block of the VPC | string | |
+| public_subnets_map | Map of {availability-zone = subnet-suffix-number}. Minimum 2 pairs. Example: {"us-east-1a" = 1, "us-east-1b" = 2} | map | |
+| private_subnets_map | Map of {availability-zone = subnet-suffix-number}. Minimum 2 pairs. Example: {"us-east-1a" = 3, "us-east-1b" = 4} | map | |
+| subnets_bit_length | Number of additional bits to extend the VPC CIDR. For example, /16 CIDR with 4-bit length results in /20 subnets. | number | |
+| gateway_name | (Optional) The name tag of the Security Gateway instances | string | **Default:** Check-Point-Cluster-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| volume_encryption | KMS or CMK key identifier. Use key ID, alias, or ARN. Prefix key alias with 'alias/' (e.g., alias/aws/ebs). | string | **Default:** alias/aws/ebs |
+| enable_instance_connect | Enable AWS Instance Connect. [More info](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents accidental termination. Note: Enabling this will prevent proper `terraform destroy`. | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| instance_tags | (Optional) A map of tags as key-value pairs. Applied to Gateway EC2 Instances | map(string) | |
+| predefined_role | (Optional) A predefined IAM role to attach to the cluster profile | string | |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components. Minimum 8 alphanumeric characters. | string | |
+| gateway_password_hash | (Optional) Admin user's password hash. | string | |
+| memberAToken | (Recommended) Token for quick connection to Smart-1 Cloud. Follow instructions in SK180501. | string | |
+| memberBToken | (Recommended) Token for quick connection to Smart-1 Cloud. Follow instructions in SK180501. | string | |
+| resources_tag_name | (Optional) Name tag prefix of the resources | string | |
+| gateway_hostname | (Optional) Host name will be appended with member-a/b. Must not contain reserved words. Refer to SK40179. | string | |
+| allow_upload_download | Automatically download Blade Contracts and other important data. | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | |
+| primary_ntp | (Optional) IPv4 address of the primary Network Time Protocol server | string | **Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) IPv4 address of the secondary Network Time Protocol server | string | **Default:** 0.pool.ntp.org |
+| gateway_maintenance_mode_password_hash | (Optional) Password hash for maintenance mode. Follow Check Point's recommendations. | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------|--------------------------------------------------------------|
+| ami_id | The ami id of the deployed Security Cross AZ Cluster members |
+| cluster_public_ip | The public address of the cluster |
+| member_a_public_ip | The public address of member A |
+| member_b_public_ip | The public address of member B |
+| member_a_ssh | SSH command to member A |
+| member_b_ssh | SSH command to member B |
+| member_a_url | URL to the member A portal |
+| member_b_url | URL to the member B portal |
diff --git a/modules/cross_az_cluster_master/locals.tf b/modules/cross_az_cluster_master/locals.tf
new file mode 100755
index 0000000..68e4523
--- /dev/null
+++ b/modules/cross_az_cluster_master/locals.tf
@@ -0,0 +1,58 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ create_iam_role = var.predefined_role == "" ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ is_both_tokens_used = length(var.memberAToken) > 0 == length(var.memberBToken) > 0
+ validation_message_both = "Smart-1 Cloud Tokens for member A and member B can not be empty."
+ //Will fail if var.memberAToken is empty and var.memberBToken isn't and vice versa
+ regex_s1c_validate = regex("^$", (local.is_both_tokens_used ? "" : local.validation_message_both))
+
+ is_tokens_used = length(var.memberAToken) > 0
+ is_both_tokens_the_same = var.memberAToken == var.memberBToken
+ validation_message_unique = "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
+ //Will fail if both s1c tokens are the same
+ regex_s1c_unique = local.is_tokens_used ? regex("^$", (local.is_both_tokens_the_same ? local.validation_message_unique : "")) : ""
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.gateway_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.gateway_hostname) == var.gateway_hostname ? 0 : "Variable [gateway_hostname] must be a valid hostname label or an empty string"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ volume_type_allowed_values = [
+ "gp3",
+ "gp2"]
+ // will fail if [var.VolumeType] is invalid:
+ validate_volume_type = index(local.volume_type_allowed_values, var.volume_type)
+}
diff --git a/modules/cross_az_cluster_master/main.tf b/modules/cross_az_cluster_master/main.tf
new file mode 100755
index 0000000..fc0dfec
--- /dev/null
+++ b/modules/cross_az_cluster_master/main.tf
@@ -0,0 +1,64 @@
+
+// --- VPC ---
+module "launch_vpc" {
+ source = "../vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = var.private_subnets_map
+ subnets_bit_length = var.subnets_bit_length
+}
+
+resource "aws_route_table" "private_subnet_rtb" {
+ depends_on = [module.launch_vpc]
+ vpc_id = module.launch_vpc.vpc_id
+ tags = {
+ Name = "Private Subnets Route Table"
+ }
+}
+resource "aws_route_table_association" "private_rtb_to_private_subnets_a" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ route_table_id = aws_route_table.private_subnet_rtb.id
+ subnet_id = module.launch_vpc.private_subnets_ids_list[0]
+}
+resource "aws_route_table_association" "private_rtb_to_private_subnets_b" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ route_table_id = aws_route_table.private_subnet_rtb.id
+ subnet_id = module.launch_vpc.private_subnets_ids_list[1]
+}
+
+module "launch_cluster_into_vpc" {
+ source = "../cross_az_cluster"
+
+
+ vpc_id = module.launch_vpc.vpc_id
+ public_subnet_ids = module.launch_vpc.public_subnets_ids_list
+ private_subnet_ids = module.launch_vpc.private_subnets_ids_list
+ private_route_table = aws_route_table.private_subnet_rtb.id
+ security_rules = var.security_rules
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ volume_size = var.volume_size
+ volume_encryption = var.volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ instance_tags = var.instance_tags
+ predefined_role = var.predefined_role
+ gateway_version = var.gateway_version
+ admin_shell = var.admin_shell
+ gateway_SICKey = var.gateway_SICKey
+ memberAToken = var.memberAToken
+ memberBToken = var.memberBToken
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ resources_tag_name = var.resources_tag_name
+ gateway_hostname = var.gateway_hostname
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = var.gateway_bootstrap_script
+ primary_ntp = var.primary_ntp
+ secondary_ntp = var.secondary_ntp
+ volume_type = var.volume_type
+}
diff --git a/modules/cross_az_cluster_master/output.tf b/modules/cross_az_cluster_master/output.tf
new file mode 100755
index 0000000..c1f4738
--- /dev/null
+++ b/modules/cross_az_cluster_master/output.tf
@@ -0,0 +1,24 @@
+output "ami_id" {
+ value = module.launch_cluster_into_vpc.ami_id
+}
+output "cluster_public_ip" {
+ value = module.launch_cluster_into_vpc.cluster_public_ip
+}
+output "member_a_public_ip" {
+ value = module.launch_cluster_into_vpc.member_a_public_ip
+}
+output "member_b_public_ip" {
+ value = module.launch_cluster_into_vpc.member_b_public_ip
+}
+output "member_a_ssh" {
+ value = module.launch_cluster_into_vpc.member_a_ssh
+}
+output "member_b_ssh" {
+ value = module.launch_cluster_into_vpc.member_b_ssh
+}
+output "member_a_url" {
+ value = module.launch_cluster_into_vpc.member_a_url
+}
+output "member_b_url" {
+ value = module.launch_cluster_into_vpc.member_b_url
+}
\ No newline at end of file
diff --git a/modules/cross_az_cluster_master/variables.tf b/modules/cross_az_cluster_master/variables.tf
new file mode 100755
index 0000000..00bc971
--- /dev/null
+++ b/modules/cross_az_cluster_master/variables.tf
@@ -0,0 +1,177 @@
+// Module: Check Point CloudGuard Network Security Cross AZ Cluster into a new VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1 \"us-east-1b\" = 2} ) "
+}
+variable "private_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 3 \"us-east-1b\" = 4} ) "
+
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+
+// --- EC2 Instance Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Cluster-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_type" {
+ type = string
+ description = "General Purpose SSD Volume Type"
+ default = "gp3"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instance"
+ default = {}
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the cluster profile"
+ default = ""
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Quick connect to Smart-1 Cloud (Recommended) ---
+variable "memberAToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+variable "memberBToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) Name tag prefix of the resources"
+ default = ""
+}
+variable "gateway_hostname" {
+ type = string
+ description = "(Optional) The host name will be appended with member-a/b accordingly"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/cross_az_cluster_master/versions.tf b/modules/cross_az_cluster_master/versions.tf
new file mode 100755
index 0000000..c138bbb
--- /dev/null
+++ b/modules/cross_az_cluster_master/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
diff --git a/modules/custom_autoscale/locals.tf b/modules/custom_autoscale/locals.tf
new file mode 100755
index 0000000..1a9b690
--- /dev/null
+++ b/modules/custom_autoscale/locals.tf
@@ -0,0 +1,9 @@
+locals {
+ asg_name = format("%s%s-servers", var.prefix != "" ? format("%s-", var.prefix) : "", var.asg_name)
+
+ regex_valid_server_ami = "^(ami-(([0-9a-f]{8})|([0-9a-f]{17})))?$"
+ // Will fail if var.server_ami is invalid
+ regex_server_ami = regex(local.regex_valid_server_ami, var.server_ami) == var.server_ami ? 0 : "Amazon Machine Image ID must be in the form ami-xxxxxxxx or ami-xxxxxxxxxxxxxxxxx"
+
+ provided_target_groups_condition = var.servers_target_groups != "" ? true : false
+}
\ No newline at end of file
diff --git a/modules/custom_autoscale/main.tf b/modules/custom_autoscale/main.tf
new file mode 100755
index 0000000..c361388
--- /dev/null
+++ b/modules/custom_autoscale/main.tf
@@ -0,0 +1,94 @@
+resource "aws_security_group" "servers_security_group" {
+ count = var.deploy_internal_security_group ? 1 : 0
+ name_prefix = format("%s_ServersSecurityGroup", local.asg_name)
+ description = "Servers security group"
+ vpc_id = var.vpc_id
+
+ ingress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ tags = {
+ Name = format("%s_ServersSecurityGroup", local.asg_name)
+ }
+}
+
+
+resource "aws_launch_template" "servers_launch_template" {
+ name_prefix = local.asg_name
+ network_interfaces {
+ associate_public_ip_address = var.allocate_public_address
+ security_groups = var.deploy_internal_security_group ? [aws_security_group.servers_security_group[0].id] : [var.source_security_group]
+ }
+ key_name = var.key_name
+ image_id = var.server_ami
+ description = "Initial template version"
+ monitoring {
+ enabled = true
+ }
+ instance_type = var.servers_instance_type
+}
+resource "aws_autoscaling_group" "servers_group" {
+ name_prefix = local.asg_name
+ vpc_zone_identifier = var.servers_subnets
+ launch_template {
+ name = aws_launch_template.servers_launch_template.name
+ version = aws_launch_template.servers_launch_template.latest_version
+ }
+ min_size = var.servers_min_group_size
+ max_size = var.servers_max_group_size
+ target_group_arns = local.provided_target_groups_condition ? [var.servers_target_groups] : []
+
+ tag {
+ key = "Name"
+ value = format("%s%s", var.prefix != "" ? format("%s-", var.prefix) : "", var.server_name)
+ propagate_at_launch = true
+ }
+}
+resource "aws_autoscaling_policy" "scale_up_policy" {
+ adjustment_type = "ChangeInCapacity"
+ autoscaling_group_name = aws_autoscaling_group.servers_group.name
+ name = "scale_up_policy"
+ cooldown = 300
+ scaling_adjustment = 1
+}
+resource "aws_autoscaling_policy" "scale_down_policy" {
+ adjustment_type = "ChangeInCapacity"
+ autoscaling_group_name = aws_autoscaling_group.servers_group.name
+ name = "scale_down_policy"
+ cooldown = 300
+ scaling_adjustment = -1
+}
+resource "aws_cloudwatch_metric_alarm" "cpu_alarm_high" {
+ alarm_description = "Scale-up if CPU > 80% for 10 minutes"
+ metric_name = "CPUUtilization"
+ namespace = "AWS/EC2"
+ statistic = "Average"
+ period = "300"
+ evaluation_periods = "2"
+ threshold = "80"
+ alarm_actions = [aws_autoscaling_policy.scale_up_policy.arn]
+ dimensions = {
+ AutoScalingGroupName = aws_autoscaling_group.servers_group.name
+ }
+ comparison_operator = "GreaterThanThreshold"
+ alarm_name = "cpu_alarm_high"
+}
+resource "aws_cloudwatch_metric_alarm" "cpu_alarm_low" {
+ alarm_description = "Scale-down if CPU < 60% for 10 minutes"
+ metric_name = "CPUUtilization"
+ namespace = "AWS/EC2"
+ statistic = "Average"
+ period = "300"
+ evaluation_periods = "2"
+ threshold = "60"
+ alarm_actions = [aws_autoscaling_policy.scale_down_policy.arn]
+ dimensions = {
+ AutoScalingGroupName = aws_autoscaling_group.servers_group.name
+ }
+ comparison_operator = "LessThanThreshold"
+ alarm_name = "cpu_alarm_low"
+}
\ No newline at end of file
diff --git a/modules/custom_autoscale/variables.tf b/modules/custom_autoscale/variables.tf
new file mode 100755
index 0000000..89acb2d
--- /dev/null
+++ b/modules/custom_autoscale/variables.tf
@@ -0,0 +1,97 @@
+// Module: Auto Scaling group of workload servers
+
+// --- Environment ---
+variable "prefix" {
+ type = string
+ description = "(Optional) Instances name prefix"
+ default = ""
+ validation {
+ condition = length(var.prefix) <= 40
+ error_message = "Prefix can not exceed 40 characters."
+ }
+}
+variable "asg_name" {
+ type = string
+ description = "Autoscaling Group name"
+ default = "Check-Point-ASG-tf"
+ validation {
+ condition = length(var.asg_name) <= 100
+ error_message = "Autoscaling Group name can not exceed 100 characters."
+ }
+}
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+ description = "Select an existing VPC"
+}
+variable "servers_subnets" {
+ type = list(string)
+ description = "Provide at least 2 private subnet IDs in the chosen VPC, separated by commas (e.g. subnet-0d72417c,subnet-1f61306f,subnet-1061d06f)"
+}
+
+// --- EC2 Instances Configuration ---
+variable "server_ami" {
+ type = string
+ description = "The Amazon Machine Image ID of a preconfigured web server (e.g. ami-0dc7dc63)"
+}
+variable "server_name" {
+ type = string
+ description = "AMI of the servers"
+ default = "Server-tf"
+}
+variable "servers_instance_type" {
+ type = string
+ description = "The EC2 instance type for the web servers"
+ default = "t3.micro"
+}
+module "validate_servers_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "server"
+ instance_type = var.servers_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "allocate_public_address" {
+ type = bool
+ description = "Allocate an elastic IP for each server"
+ default = false
+}
+
+// --- Auto Scaling Configuration ---
+variable "servers_min_group_size" {
+ type = number
+ description = "The minimal number of servers in the Auto Scaling group"
+ default = 2
+}
+resource "null_resource" "servers_min_group_size_too_small" {
+ // servers_min_group_size validation - resource will not be created if the size is smaller than 1
+ count = var.servers_min_group_size >= 1 ? 0 : "servers_min_group_size must be at least 1"
+}
+variable "servers_max_group_size" {
+ type = number
+ description = "The maximal number of servers in the Auto Scaling group"
+ default = 10
+}
+resource "null_resource" "servers_max_group_size_too_small" {
+ // servers_max_group_size validation - resource will not be created if the size is smaller than 1
+ count = var.servers_max_group_size >= 1 ? 0 : "servers_max_group_size must be at least 1"
+}
+variable "servers_target_groups" {
+ type = string
+ description = "(Optional) An optional list of Target Groups to associate with the Auto Scaling group (comma separated list of ARNs, without spaces)"
+ default = ""
+}
+variable "deploy_internal_security_group" {
+ type = bool
+ description = "Select 'false' to use an existing Security group"
+ default = true
+}
+variable "source_security_group" {
+ type = string
+ description = "The ID of Security Group from which access will be allowed to the instances in this Auto Scaling group"
+ default = ""
+}
\ No newline at end of file
diff --git a/modules/common/elastic_ip/locals.tf b/modules/elastic_ip/locals.tf
similarity index 100%
rename from modules/common/elastic_ip/locals.tf
rename to modules/elastic_ip/locals.tf
diff --git a/modules/common/elastic_ip/main.tf b/modules/elastic_ip/main.tf
similarity index 100%
rename from modules/common/elastic_ip/main.tf
rename to modules/elastic_ip/main.tf
diff --git a/modules/common/elastic_ip/output.tf b/modules/elastic_ip/output.tf
similarity index 100%
rename from modules/common/elastic_ip/output.tf
rename to modules/elastic_ip/output.tf
diff --git a/modules/common/elastic_ip/variables.tf b/modules/elastic_ip/variables.tf
similarity index 100%
rename from modules/common/elastic_ip/variables.tf
rename to modules/elastic_ip/variables.tf
diff --git a/modules/gateway/README.md b/modules/gateway/README.md
index dbf0042..389a02d 100755
--- a/modules/gateway/README.md
+++ b/modules/gateway/README.md
@@ -18,6 +18,61 @@ This solution uses the following modules:
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/gateway"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ public_subnet_id = "subnet-123456"
+ private_subnet_id = "subnet-345678"
+ private_route_table = "rtb-12345678"
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Gateway-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ gateway_TokenKey = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+
+ // --- Automatic Provisioning with Security Management Server Settings (optional) ---
+ control_gateway_over_public_or_private_address = "private"
+ management_server = ""
+ configuration_template = ""
+}
+ ```
+
- Conditional creation
- To create an Elastic IP and associate it to the Gateway instance:
```
@@ -48,7 +103,7 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| instance_tags | A map of tags as key=value pairs. All tags will be added to the Security Gateway EC2 Instance | map(string) | **Default:** {} |
| gateway_version | Gateway version and license | string | - R81.10-BYOL
- R81.10-PAYG-NGTP
- R81.10-PAYG-NGTX
- R81.20-BYOL
- R81.20-PAYG-NGTP
- R81.20-PAYG-NGTX
- R82-BYOL
- R82-PAYG-NGTP
- R82-PAYG-NGTX
**Default:** R81.20-BYOL |
| admin_shell | Set the admin shell to enable advanced command-line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh
**Default:** /etc/cli.sh |
-| gateway_SIC_Key | The Secure Internal Communication key for trusted connection between Check Point components. Choose a random 8+ string | string | **Default:** 12345678 |
+| gateway_SIC_Key | The Secure Internal Communication key for trusted connection between Check Point components. Choose a random 8+ string | string | |
| gateway_password_hash | (Optional) Admin user's password hash (use 'openssl passwd -6 PASSWORD' to generate hash) | string | **Default:** "" |
| allow_upload_download | Automatically download Blade Contracts and other important data | bool | true/false
**Default:** true |
| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
@@ -67,6 +122,12 @@ Follow best practices for using CGNS modules on [the root page](https://registry
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|-----------------------|----------------------------------------------------|
| ami_id | The ami id of the deployed Security Gateway |
diff --git a/modules/gateway/main.tf b/modules/gateway/main.tf
index 662baa6..b7ec0ed 100755
--- a/modules/gateway/main.tf
+++ b/modules/gateway/main.tf
@@ -6,7 +6,7 @@ module "amis" {
}
module "common_permissive_sg" {
- source = "../common/permissive_sg"
+ source = "../permissive_sg"
security_rules = var.security_rules
vpc_id = var.vpc_id
resources_tag_name = var.resources_tag_name
@@ -62,7 +62,7 @@ resource "aws_network_interface" "private_eni" {
}
module "common_eip" {
- source = "../common/elastic_ip"
+ source = "../elastic_ip"
depends_on = [
module.common_gateway_instance
]
@@ -73,14 +73,14 @@ module "common_eip" {
}
module "common_internal_default_route" {
- source = "../common/internal_default_route"
+ source = "../internal_default_route"
private_route_table = var.private_route_table
internal_eni_id = aws_network_interface.private_eni.id
}
module "common_gateway_instance" {
- source = "../common/gateway_instance"
+ source = "../gateway_instance"
external_eni_id = aws_network_interface.public_eni.id
internal_eni_id = aws_network_interface.private_eni.id
diff --git a/modules/gateway/variables.tf b/modules/gateway/variables.tf
index a5fb592..7435cba 100755
--- a/modules/gateway/variables.tf
+++ b/modules/gateway/variables.tf
@@ -30,7 +30,7 @@ variable "gateway_instance_type" {
default = "c6in.xlarge"
}
module "validate_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "gateway"
instance_type = var.gateway_instance_type
@@ -86,7 +86,7 @@ variable "gateway_version" {
default = "R81.20-BYOL"
}
module "validate_gateway_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "gateway"
version_license = var.gateway_version
@@ -173,7 +173,6 @@ variable "configuration_template" {
error_message = "The configuration_template name can not exceed 30 characters."
}
}
-
variable "security_rules" {
description = "List of security rules for ingress and egress"
type = list(object({
diff --git a/modules/gateway_instance/gateway_userdata.yaml b/modules/gateway_instance/gateway_userdata.yaml
new file mode 100755
index 0000000..dfd41fa
--- /dev/null
+++ b/modules/gateway_instance/gateway_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" "smart1CloudToken=\"${TokenKey}\"" installationType=\"gateway\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"gateway\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${GatewayBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/common/gateway_instance/locals.tf b/modules/gateway_instance/locals.tf
similarity index 100%
rename from modules/common/gateway_instance/locals.tf
rename to modules/gateway_instance/locals.tf
diff --git a/modules/common/gateway_instance/main.tf b/modules/gateway_instance/main.tf
similarity index 100%
rename from modules/common/gateway_instance/main.tf
rename to modules/gateway_instance/main.tf
diff --git a/modules/common/gateway_instance/output.tf b/modules/gateway_instance/output.tf
similarity index 100%
rename from modules/common/gateway_instance/output.tf
rename to modules/gateway_instance/output.tf
diff --git a/modules/common/gateway_instance/variables.tf b/modules/gateway_instance/variables.tf
similarity index 100%
rename from modules/common/gateway_instance/variables.tf
rename to modules/gateway_instance/variables.tf
diff --git a/modules/gateway_master/README.md b/modules/gateway_master/README.md
index 50e4f2b..94150ea 100755
--- a/modules/gateway_master/README.md
+++ b/modules/gateway_master/README.md
@@ -27,7 +27,65 @@ Follow best practices for using CGNS modules on [the root page](https://registry
```
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/gateway_master"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ }
+ private_subnets_map = {
+ "us-east-1a" = 2
+ }
+ subnets_bit_length = 8
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Gateway-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = ""
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ gateway_TokenKey = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+
+ // --- (Optional) Automatic Provisioning with Security Management Server Settings ---
+ control_gateway_over_public_or_private_address = "private"
+ management_server = ""
+ configuration_template = ""
+}
+```
## Inputs
+
| Name | Description | Type | Allowed values |
|------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| vpc_cidr | The CIDR block of the VPC | string | |
@@ -60,10 +118,16 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| management_server | (Optional) The name that represents the Security Management Server in the automatic provisioning configuration | string | **Default:** "" |
| configuration_template | (Optional) A name of a Security Gateway configuration template in the automatic provisioning configuration | string | **Default:** "" |
| gateway_maintenance_mode_password_hash | (Optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here). | string | **Default:** "" |
-| security_rules | List of security rules for ingress and egress. | list(object(
{ direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)})) | **Default:** []|
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|------------------------------|----------------------------------------------------|
| vpc_id | The id of the deployed vpc |
diff --git a/modules/gateway_master/variables.tf b/modules/gateway_master/variables.tf
index 1abba13..4d11230 100755
--- a/modules/gateway_master/variables.tf
+++ b/modules/gateway_master/variables.tf
@@ -32,7 +32,7 @@ variable "gateway_instance_type" {
default = "c6in.xlarge"
}
module "validate_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "gateway"
instance_type = var.gateway_instance_type
@@ -88,7 +88,7 @@ variable "gateway_version" {
default = "R81.20-BYOL"
}
module "validate_gateway_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "gateway"
version_license = var.gateway_version
@@ -176,7 +176,6 @@ variable "configuration_template" {
error_message = "The configuration_template name can not exceed 30 characters."
}
}
-
variable "security_rules" {
description = "List of security rules for ingress and egress"
type = list(object({
diff --git a/modules/gwlb/README.md b/modules/gwlb/README.md
index fffad53..a244750 100755
--- a/modules/gwlb/README.md
+++ b/modules/gwlb/README.md
@@ -22,6 +22,68 @@ This solution uses the following modules:
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/gwlb"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345"
+ subnet_ids = ["subnet-123457", "subnet-123456"]
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ volume_size = 100
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+ management_server = "CP-Management-gwlb-tf"
+ configuration_template = "gwlb-configuration"
+ admin_shell = "/etc/cli.sh"
+
+ // --- Gateway Load Balancer Configuration ---
+ gateway_load_balancer_name = "gwlb1"
+ target_group_name = "tg1"
+ connection_acceptance_required = "false"
+ enable_cross_zone_load_balancing = "true"
+
+ // --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = "Check-Point-GW-tf"
+ gateway_instance_type = "c5.xlarge"
+ minimum_group_size = 2
+ maximum_group_size = 10
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ gateways_provision_address_type = "private"
+ allocate_public_IP = false
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+
+ // --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ gateways_policy = "Standard"
+ gateway_management = "Locally managed"
+ admin_cidr = ""
+ gateways_addresses = ""
+
+ // --- Other parameters ---
+ volume_type = "gp3"
+}
+```
+
+
- Conditional creation
- To enable cloudwatch for GWLB:
```
@@ -32,10 +94,7 @@ Follow best practices for using CGNS modules on [the root page](https://registry
```
management_deploy = true
```
-- To tear down your resources:
- ```
- terraform destroy
- ```
+
## Inputs
| Name | Description | Type | Allowed Values |
@@ -57,18 +116,18 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| connection_acceptance_required | Indicate whether requests from service consumers to create an endpoint to your service must be accepted. Default is set to false (acceptance not required). | bool | true/false
**Default:** false |
| enable_cross_zone_load_balancing | Select 'true' to enable cross-az load balancing. NOTE! this may cause a spike in cross-az charges. | bool | true/false
**Default:** true |
| gateway_name | The name tag of the Security Gateway instances. (optional) | string | **Default:** Check-Point-GW-tf |
-| gateway_instance_type | The instance type of the Security Gateways | string | - c5.xlarge
**Default:** c5.xlarge |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
| gateways_min_group_size | The minimal number of Security Gateways | number | **Default:** 2 |
| gateways_max_group_size | The maximal number of Security Gateways | number | **Default:** 10 |
| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R81.20-PAYG-NGTX
- R82-BYOL
- R82-PAYG-NGTP
- R82-PAYG-NGTX
**Default:** R81.20-BYOL |
| gateway_password_hash | (Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash) | string | |
-| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters | string | **Default:** 12345678 |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters | string | |
| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
| gateway_bootstrap_script | (Optional) An optional script with semicolon (;) separated commands to run on the initial boot | string | |
| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address. | string | - private
- public
**Default:** private |
| allocate_public_IP | Allocate a Public IP for gateway members. | bool | true/false
**Default:** false |
| management_deploy | Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section | bool | true/false
**Default:** true |
-| management_instance_type | The EC2 instance type of the Security Management Server | string | - c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
+| management_instance_type | The EC2 instance type of the Security Management Server | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
| management_version | The license to install on the Security Management Server | string | - R81.10-BYOL
- R81.10-PAYG
- R81.20-BYOL
- R81.20-PAYG
**Default:** R81.20-BYOL |
| management_password_hash | (Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash) | string | |
| gateways_policy | The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group | string | **Default:** Standard |
@@ -80,6 +139,12 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| management_maintenance_mode_password_hash | Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command "grub2-mkpasswd-pbkdf2" on Linux and paste it here). | string | |
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|---------------------|---------------------------------------------------------------------------------------|
| managment_public_ip | The deployed Security Management AWS instance public IP |
diff --git a/modules/gwlb/main.tf b/modules/gwlb/main.tf
index 2359623..60f1d14 100755
--- a/modules/gwlb/main.tf
+++ b/modules/gwlb/main.tf
@@ -1,7 +1,7 @@
module "gateway_load_balancer" {
- source = "../common/load_balancer"
+ source = "../load_balancer"
load_balancers_type = "gateway"
instances_subnets = var.subnet_ids
diff --git a/modules/gwlb/variables.tf b/modules/gwlb/variables.tf
index cf5641b..ad0988f 100755
--- a/modules/gwlb/variables.tf
+++ b/modules/gwlb/variables.tf
@@ -110,7 +110,7 @@ variable "gateway_instance_type" {
default = "c6in.xlarge"
}
module "validate_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "gateway"
instance_type = var.gateway_instance_type
@@ -131,7 +131,7 @@ variable "gateway_version" {
default = "R81.20-BYOL"
}
module "validate_gateway_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "gwlb_gw"
version_license = var.gateway_version
@@ -193,7 +193,7 @@ variable "management_instance_type" {
default = "m5.xlarge"
}
module "validate_management_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "management"
instance_type = var.management_instance_type
@@ -204,7 +204,7 @@ variable "management_version" {
default = "R81.20-BYOL"
}
module "validate_management_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "management"
version_license = var.management_version
diff --git a/modules/gwlb_master/README.md b/modules/gwlb_master/README.md
index d4335d5..106c009 100755
--- a/modules/gwlb_master/README.md
+++ b/modules/gwlb_master/README.md
@@ -24,6 +24,71 @@ This solution uses the following modules:
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/gwlb_master"
+ version = "1.0.2"
+
+ // --- Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ "us-east-1b" = 2
+ }
+ subnets_bit_length = 8
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ volume_size = 100
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+ management_server = "CP-Management-gwlb-tf"
+ configuration_template = "gwlb-configuration"
+ admin_shell = "/etc/cli.sh"
+
+ // --- Gateway Load Balancer Configuration ---
+ gateway_load_balancer_name = "gwlb1"
+ target_group_name = "tg1"
+ connection_acceptance_required = "false"
+ enable_cross_zone_load_balancing = "true"
+
+ // --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = "Check-Point-GW-tf"
+ gateway_instance_type = "c5.xlarge"
+ minimum_group_size = 2
+ maximum_group_size = 10
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ gateways_provision_address_type = "private"
+ allocate_public_IP = false
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+
+ // --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ gateways_policy = "Standard"
+ gateway_management = "Locally managed"
+ admin_cidr = ""
+ gateways_addresses = ""
+
+ // --- Other parameters ---
+ volume_type = "gp3"
+}
+```
+
+
## Inputs
| Name | Description | Type | Allowed values |
@@ -46,7 +111,7 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| connection_acceptance_required | Indicate whether requests from service consumers to create an endpoint to your service must be accepted. Default is set to false (acceptance not required). | bool | true/false
**Default:** false |
| enable_cross_zone_load_balancing | Select 'true' to enable cross-az load balancing. NOTE: this may cause a spike in cross-az charges. | bool | true/false
**Default:** true |
| gateway_name | The name tag of the Security Gateway instances. (optional) | string | **Default:** Check-Point-GW-tf |
-| gateway_instance_type | The instance type of the Security Gateways | string | Various instance types (e.g., c5.xlarge, c6i.large, m5.xlarge, etc.)
**Default:** c5.xlarge |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
| gateways_min_group_size | The minimal number of Security Gateways | number | **Default:** 2 |
| gateways_max_group_size | The maximal number of Security Gateways | number | **Default:** 10 |
| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R81.20-PAYG-NGTX
- R82-BYOL
- R82-PAYG-NGTP
- R82-PAYG-NGTX
**Default:** R81.20-BYOL |
@@ -57,7 +122,7 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address | string | - private
- public
**Default:** private |
| allocate_public_IP | Allocate a Public IP for gateway members. | bool | true/false
**Default:** false |
| management_deploy | Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section | bool | true/false
**Default:** true |
-| management_instance_type | The EC2 instance type of the Security Management Server | string | Various instance types (e.g., c5.xlarge, c6i.large, m5.xlarge, etc.)
**Default:** m5.xlarge |
+| management_instance_type | The EC2 instance type of the Security Management Server | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
| management_version | The license to install on the Security Management Server | string | - R81.10-BYOL
- R81.10-PAYG
- R81.20-BYOL
- R81.20-PAYG
**Default:** R81.20-BYOL |
| management_password_hash | Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. | string | **Default:** "" |
| gateways_policy | The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group | string | **Default:** Standard |
@@ -70,6 +135,12 @@ Follow best practices for using CGNS modules on [the root page](https://registry
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|---------------------|---------------------------------------------------------------------------------------|
| managment_public_ip | The deployed Security Management AWS instance public IP |
diff --git a/modules/gwlb_master/variables.tf b/modules/gwlb_master/variables.tf
index e16c675..e003878 100755
--- a/modules/gwlb_master/variables.tf
+++ b/modules/gwlb_master/variables.tf
@@ -121,7 +121,7 @@ variable "gateway_instance_type" {
default = "c6in.xlarge"
}
module "validate_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "gateway"
instance_type = var.gateway_instance_type
@@ -142,7 +142,7 @@ variable "gateway_version" {
default = "R81.20-BYOL"
}
module "validate_gateway_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "gwlb_gw"
version_license = var.gateway_version
@@ -204,7 +204,7 @@ variable "management_instance_type" {
default = "m5.xlarge"
}
module "validate_management_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "management"
instance_type = var.management_instance_type
@@ -215,7 +215,7 @@ variable "management_version" {
default = "R81.20-BYOL"
}
module "validate_management_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "management"
version_license = var.management_version
diff --git a/modules/common/instance_type/main.tf b/modules/instance_type/main.tf
similarity index 100%
rename from modules/common/instance_type/main.tf
rename to modules/instance_type/main.tf
diff --git a/modules/common/instance_type/variables.tf b/modules/instance_type/variables.tf
similarity index 100%
rename from modules/common/instance_type/variables.tf
rename to modules/instance_type/variables.tf
diff --git a/modules/common/internal_default_route/locals.tf b/modules/internal_default_route/locals.tf
similarity index 100%
rename from modules/common/internal_default_route/locals.tf
rename to modules/internal_default_route/locals.tf
diff --git a/modules/common/internal_default_route/main.tf b/modules/internal_default_route/main.tf
similarity index 100%
rename from modules/common/internal_default_route/main.tf
rename to modules/internal_default_route/main.tf
diff --git a/modules/common/internal_default_route/output.tf b/modules/internal_default_route/output.tf
similarity index 100%
rename from modules/common/internal_default_route/output.tf
rename to modules/internal_default_route/output.tf
diff --git a/modules/common/internal_default_route/variables.tf b/modules/internal_default_route/variables.tf
similarity index 100%
rename from modules/common/internal_default_route/variables.tf
rename to modules/internal_default_route/variables.tf
diff --git a/modules/common/load_balancer/main.tf b/modules/load_balancer/main.tf
similarity index 100%
rename from modules/common/load_balancer/main.tf
rename to modules/load_balancer/main.tf
diff --git a/modules/common/load_balancer/output.tf b/modules/load_balancer/output.tf
similarity index 100%
rename from modules/common/load_balancer/output.tf
rename to modules/load_balancer/output.tf
diff --git a/modules/common/load_balancer/variables.tf b/modules/load_balancer/variables.tf
similarity index 100%
rename from modules/common/load_balancer/variables.tf
rename to modules/load_balancer/variables.tf
diff --git a/modules/management/README.md b/modules/management/README.md
index e24885c..f5f3aba 100755
--- a/modules/management/README.md
+++ b/modules/management/README.md
@@ -19,13 +19,68 @@ This solution uses the following modules:
## Usage
Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/management"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ subnet_id = "subnet-abc123"
+
+ // --- EC2 Instances Configuration ---
+ management_name = "CP-Management-tf"
+ management_instance_type = "m5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- IAM Permissions ---
+ iam_permissions = "Create with read permissions"
+ predefined_role = ""
+ sts_roles = []
+
+ // --- Check Point Settings ---
+ management_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ // --- Security Management Server Settings ---
+ management_hostname = "mgmt-tf"
+ management_installation_type = "Primary management"
+ SICKey = ""
+ allow_upload_download = "true"
+ gateway_management = "Locally managed"
+ admin_cidr = "0.0.0.0/0"
+ gateway_addresses = "0.0.0.0/0"
+ primary_ntp = ""
+ secondary_ntp = ""
+ management_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+}
+```
+
+
+
+
## Inputs
| Name | Description | Type | Allowed values |
|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| vpc_id | The VPC id in which to deploy | string | |
| subnet_id | To access the instance from the internet, make sure the subnet has a route to the internet | string | |
| management_name | (Optional) The name tag of the Security Management instance | string | **Default:** Check-Point-Management-tf |
-| management_instance_type | The instance type of the Security Management Server | string | - c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
+| management_instance_type | The instance type of the Security Management Server | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | |
| allocate_and_associate_eip | If set to true, an elastic IP will be allocated and associated with the launched instance | bool | true/false
**Default:** true |
| volume_encryption | KMS or CMK key Identifier: Use key ID, alias, or ARN. Key alias should be prefixed with 'alias/' (e.g., for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs') | string | **Default:** alias/aws/ebs |
@@ -49,12 +104,20 @@ Follow best practices for using CGNS modules on [the root page](https://registry
| secondary_ntp | (Optional) The IPv4 addresses of Network Time Protocol secondary server | string | **Default:** 0.pool.ntp.org |
| management_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | **Default:** "" |
| management_maintenance_mode_password_hash | Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. | string | **Default:** "" |
-| security_rules | List of security rules for ingress and egress. | list(object(
{ direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)})) | **Default:** []|
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
| Name | Description |
|--------------------------|--------------------------------------------------------------|
| management_instance_id | The deployed Security Management Server AWS instance id |
diff --git a/modules/management/main.tf b/modules/management/main.tf
index 61e72b4..bc6d46b 100755
--- a/modules/management/main.tf
+++ b/modules/management/main.tf
@@ -90,7 +90,6 @@ resource "aws_security_group" "management_sg" {
cidr_blocks = [var.admin_cidr]
}
- // Add dynamic rules from the "security_rules" variable
dynamic "ingress" {
for_each = [for rule in var.security_rules : rule if rule.direction == "ingress"]
content {
diff --git a/modules/management/management_userdata.yaml b/modules/management/management_userdata.yaml
index 1b87042..c2e48c1 100755
--- a/modules/management/management_userdata.yaml
+++ b/modules/management/management_userdata.yaml
@@ -1,4 +1,4 @@
#cloud-config
runcmd:
- |
- python3 /etc/cloud_config.py sicKey=\"${SICKey}\" installationType=\"management\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"20241027\" templateName=\"management\" templateType=\"terraform\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" "management_installation_type=\"${ManagementInstallationType}\"" adminSubnet=\"${AdminSubnet}\" allocatePublicAddress=\"${AllocateElasticIP}\" overTheInternet=\"${PubMgmt}\" bootstrapScript64=\"${BootstrapScript}\"
\ No newline at end of file
+ python3 /etc/cloud_config.py sicKey=\"${SICKey}\" installationType=\"management\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"management\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" "management_installation_type=\"${ManagementInstallationType}\"" adminSubnet=\"${AdminSubnet}\" allocatePublicAddress=\"${AllocateElasticIP}\" overTheInternet=\"${PubMgmt}\" bootstrapScript64=\"${BootstrapScript}\"
\ No newline at end of file
diff --git a/modules/management/variables.tf b/modules/management/variables.tf
index f87a7e3..3addb5d 100755
--- a/modules/management/variables.tf
+++ b/modules/management/variables.tf
@@ -21,7 +21,7 @@ variable "management_instance_type" {
default = "m5.xlarge"
}
module "validate_instance_type" {
- source = "../common/instance_type"
+ source = "../instance_type"
chkp_type = "management"
instance_type = var.management_instance_type
@@ -94,7 +94,7 @@ variable "management_version" {
default = "R81.20-BYOL"
}
module "validate_management_version" {
- source = "../common/version_license"
+ source = "../version_license"
chkp_type = "management"
version_license = var.management_version
@@ -186,4 +186,4 @@ variable "security_rules" {
}))
default = []
-}
+}
\ No newline at end of file
diff --git a/modules/mds/README.md b/modules/mds/README.md
new file mode 100755
index 0000000..fb6047d
--- /dev/null
+++ b/modules/mds/README.md
@@ -0,0 +1,126 @@
+# Check Point CloudGuard Network Multi-Domain Server Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Multi-Domain Server into an existing VPC.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Multi-Domain Management Deployment on AWS](https://supportcenter.us.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk143213) for additional information
+
+This solution uses the following modules:
+- amis
+- cme_iam_role
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/mds"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ subnet_id = "subnet-abc123"
+
+ // --- EC2 Instances Configuration ---
+ mds_name = "CP-MDS-tf"
+ mds_instance_type = "m5.12xlarge"
+ key_name = "publickey"
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- IAM Permissions ---
+ iam_permissions = "Create with read permissions"
+ predefined_role = ""
+ sts_roles = []
+
+ // --- Check Point Settings ---
+ mds_version = "R81.20-BYOL"
+ mds_admin_shell = "/etc/cli.sh"
+ mds_password_hash = ""
+ mds_maintenance_mode_password_hash = ""
+
+ // --- Multi-Domain Server Settings ---
+ mds_hostname = "mds-tf"
+ mds_SICKey = ""
+ allow_upload_download = "true"
+ mds_installation_type = "Primary Multi-Domain Server"
+ admin_cidr = "0.0.0.0/0"
+ gateway_addresses = "0.0.0.0/0"
+ primary_ntp = ""
+ secondary_ntp = ""
+ mds_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+}
+ ```
+
+- Conditional creation
+ - To create IAM Role:
+ ```
+ iam_permissions = "Create with read permissions" | "Create with read-write permissions" | "Create with assume role permissions (specify an STS role ARN)"
+ and
+ mds_installation_type = "Primary Multi-Domain Server"
+ ```
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|----------------------------------------------------------------------------------------------------|
+| vpc_id | The VPC ID in which to deploy | string | |
+| subnet_id | Subnet with a route to the internet | string | |
+| mds_name | (Optional) Name tag of the Multi-Domain Server | string | **Default:** Check-Point-MDS-tf |
+| mds_instance_type | Instance type of the Multi-Domain Server | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.12xlarge |
+| key_name | EC2 Key Pair name to allow SSH access | string | |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| volume_encryption | KMS or CMK key identifier (e.g., alias/aws/ebs) | string | **Default:** alias/aws/ebs |
+| enable_instance_connect | Enable SSH connection over AWS web console | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevent accidental termination | bool | true/false
**Default:** false |
+| instance_tags | (Optional) Map of tags as key-value pairs | map(string) | |
+| metadata_imdsv2_required | Deploy instance with metadata v2 token required | bool | true/false
**Default:** true |
+| iam_permissions | IAM role to attach to instance profile | string | - None
- Use existing
- Create with assume role permissions
- Create with read/write
**Default:** Create with read permissions |
+| predefined_role | (Optional) Predefined IAM role (only applies with 'Use existing') | string | |
+| sts_roles | (Optional) List of IAM roles for STS assumption (only applies with 'Create with assume role permissions') | list(string) | |
+| mds_version | Multi-Domain Server version and license | string | - R81.10-BYOL
- R81.20-BYOL
- R82-BYOL
**Default:** R81.20-BYOL |
+| mds_admin_shell | Set admin shell for advanced configurations | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| mds_password_hash | (Optional) Admin user's password hash | string | |
+| mds_hostname | (Optional) Multi-Domain Server prompt hostname | string | |
+| mds_SICKey | Secure Internal Communication key for trusted connections | string | |
+| allow_upload_download | Automatically download Blade Contracts and related data | bool | true/false
**Default:** true |
+| mds_installation_type | Multi-Domain Server installation type | string | - Primary Multi-Domain Server
- Secondary Multi-Domain Server
- Multi-Domain Log Server
**Default:** Primary Multi-Domain Server |
+| admin_cidr | CIDR for allowing access to the Multi-Domain Server | string | valid CIDR
**Default:** 0.0.0.0/0 |
+| gateway_addresses | CIDR for allowing gateway access to the Multi-Domain Server | string | valid CIDR
**Default:** 0.0.0.0/0 |
+| primary_ntp | (Optional) IPv4 address of the primary Network Time Protocol server | string | **Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) IPv4 address of the secondary Network Time Protocol server | string | **Default:** 0.pool.ntp.org |
+| mds_bootstrap_script | (Optional) Semicolon-separated commands to run during initial boot | string | |
+| mds_maintenance_mode_password_hash | (Optional) Admin user's password hash for maintenance mode | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|-------------------|----------------------------------------------------|
+| mds_instance_id | The deployed Multi-Domain Server AWS instance id |
+| mds_instance_name | The deployed Multi-Domain Server AWS instance name |
+| mds_instance_tags | The deployed Multi-Domain Server AWS tags |
diff --git a/modules/mds/locals.tf b/modules/mds/locals.tf
new file mode 100755
index 0000000..7dd690a
--- /dev/null
+++ b/modules/mds/locals.tf
@@ -0,0 +1,69 @@
+locals {
+ permissions_allowed_values = [
+ "None (configure later)",
+ "Use existing (specify an existing IAM role name)",
+ "Create with assume role permissions (specify an STS role ARN)",
+ "Create with read permissions",
+ "Create with read-write permissions"]
+ // Will fail if var.iam_permissions is invalid
+ validate_permissions = index(local.permissions_allowed_values, var.iam_permissions)
+
+ installation_type_allowed_values = [
+ "Primary Multi-Domain Server",
+ "Secondary Multi-Domain Server",
+ "Multi-Domain Log Server"]
+ // Will fail if var.mds_installation_type is invalid
+ validate_installation_type = index(local.installation_type_allowed_values, var.mds_installation_type)
+
+ primary_mds = var.mds_installation_type == "Primary Multi-Domain Server"
+ secondary_mds = var.mds_installation_type == "Secondary Multi-Domain Server"
+
+ use_role = var.iam_permissions != "None (configure later)" && local.primary_mds ? 1 : 0
+ create_iam_role = (local.primary_mds) && (var.iam_permissions == "Create with assume role permissions (specify an STS role ARN)" || var.iam_permissions == "Create with read permissions" || var.iam_permissions == "Create with read-write permissions")
+
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.mds_admin_shell)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_cidr_range = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$"
+ // Will fail if var.admin_subnet or var.gateway_addresses are invalid
+ mgmt_subnet_regex_result = regex(local.regex_valid_cidr_range, var.admin_cidr) == var.admin_cidr ? 0 : "var.admin_subnet must be a valid CIDR range"
+ gw_addr_regex_result = regex(local.regex_valid_cidr_range, var.gateway_addresses) == var.gateway_addresses ? 0 : "var.gateway_addresses must be a valid CIDR range"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.mds_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.mds_hostname) == var.mds_hostname ? 0 : "Variable [mds_hostname] must be a valid hostname label or an empty string"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ regex_valid_mds_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.mds_password_hash is invalid
+ regex_mds_password_hash = regex(local.regex_valid_mds_password_hash, var.mds_password_hash) == var.mds_password_hash ? 0 : "Variable [mds_password_hash] must be a valid password hash"
+ regex_maintenance_mode_password_hash = regex(local.regex_valid_mds_password_hash, var.mds_maintenance_mode_password_hash) == var.mds_maintenance_mode_password_hash ? 0 : "Variable [mds_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_sic_key = "(|[a-zA-Z0-9]{8,})"
+ // Will fail if var.mds_SICKey is invalid
+ regex_sic_result = regex(local.regex_valid_sic_key, var.mds_SICKey) == var.mds_SICKey ? 0 : "Variable [mds_SICKey] must be at least 8 alphanumeric characters"
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.mds_version), 0)
+
+ mds_bootstrap_script64 = base64encode(var.mds_bootstrap_script)
+ mds_SICkey_base64 = base64encode(var.mds_SICKey)
+ mds_password_hash_base64 =base64encode(var.mds_password_hash)
+ maintenance_mode_password_hash_base64 = base64encode(var.mds_maintenance_mode_password_hash)
+}
\ No newline at end of file
diff --git a/modules/mds/main.tf b/modules/mds/main.tf
new file mode 100755
index 0000000..dd3b910
--- /dev/null
+++ b/modules/mds/main.tf
@@ -0,0 +1,209 @@
+
+module "amis" {
+ source = "../amis"
+
+ version_license = var.mds_version
+ chkp_type = "mds"
+}
+
+resource "aws_security_group" "mds_sg" {
+ description = "terraform Multi-Domain Server security group"
+ vpc_id = var.vpc_id
+ name_prefix = format("%s_SecurityGroup", var.mds_name)
+ // Group name
+ tags = {
+ Name = format("%s_SecurityGroup", var.mds_name)
+ // Resource name
+ }
+ ingress {
+ from_port = 257
+ to_port = 257
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 8211
+ to_port = 8211
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18191
+ to_port = 18191
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18192
+ to_port = 18192
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18208
+ to_port = 18208
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18210
+ to_port = 18210
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18211
+ to_port = 18211
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18221
+ to_port = 18221
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 18264
+ to_port = 18264
+ protocol = "tcp"
+ cidr_blocks = [var.gateway_addresses]
+ }
+ ingress {
+ from_port = 22
+ to_port = 22
+ protocol = "tcp"
+ cidr_blocks = [var.admin_cidr]
+ }
+ ingress {
+ from_port = 443
+ to_port = 443
+ protocol = "tcp"
+ cidr_blocks = [var.admin_cidr]
+ }
+ ingress {
+ from_port = 18190
+ to_port = 18190
+ protocol = "tcp"
+ cidr_blocks = [var.admin_cidr]
+ }
+ ingress {
+ from_port = 19009
+ to_port = 19009
+ protocol = "tcp"
+ cidr_blocks = [var.admin_cidr]
+ }
+
+ dynamic "ingress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "ingress"]
+ content {
+ from_port = ingress.value.from_port
+ to_port = ingress.value.to_port
+ protocol = ingress.value.protocol
+ cidr_blocks = ingress.value.cidr_blocks
+ }
+ }
+
+ dynamic "egress" {
+ for_each = [for rule in var.security_rules : rule if rule.direction == "egress"]
+ content {
+ from_port = egress.value.from_port
+ to_port = egress.value.to_port
+ protocol = egress.value.protocol
+ cidr_blocks = egress.value.cidr_blocks
+ }
+ }
+
+ dynamic egress {
+ for_each = length([for rule in var.security_rules : rule if rule.direction == "egress"]) == 0 ? [1] : []
+ content{
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ }
+}
+
+resource "aws_iam_instance_profile" "mds_instance_profile" {
+ count = local.use_role
+ path = "/"
+ role = local.create_iam_role ? join("", module.cme_iam_role.*.cme_iam_role_name) : var.predefined_role
+}
+
+resource "aws_network_interface" "external-eni" {
+ subnet_id = var.subnet_id
+ security_groups = [aws_security_group.mds_sg.id]
+ description = "eth0"
+ source_dest_check = true
+ tags = {
+ Name = format("%s-network_interface", var.mds_name)
+ }
+}
+
+resource "aws_launch_template" "mds_launch_template" {
+ instance_type = var.mds_instance_type
+ key_name = var.key_name
+ image_id = module.amis.ami_id
+ description = "Initial launch template version"
+
+ iam_instance_profile {
+ name = local.use_role == 1 ? aws_iam_instance_profile.mds_instance_profile[0].id : ""
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.external-eni.id
+ device_index = 0
+ }
+}
+
+resource "aws_instance" "mds-instance" {
+ launch_template {
+ id = aws_launch_template.mds_launch_template.id
+ version = "$Latest"
+ }
+
+ disable_api_termination = var.disable_instance_termination
+
+ tags = merge({
+ Name = var.mds_name
+ }, var.instance_tags)
+
+ ebs_block_device {
+ device_name = "/dev/xvda"
+ volume_type = "gp2"
+ volume_size = var.volume_size
+ encrypted = local.volume_encryption_condition
+ kms_key_id = local.volume_encryption_condition ? var.volume_encryption : ""
+ }
+
+ user_data = templatefile("${path.module}/mds_userdata.yaml", {
+ // script's arguments
+ Hostname = var.mds_hostname,
+ PasswordHash = local.mds_password_hash_base64
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64
+ AllowUploadDownload = var.allow_upload_download,
+ NTPPrimary = var.primary_ntp
+ NTPSecondary = var.secondary_ntp
+ Shell = var.mds_admin_shell,
+ AdminSubnet = var.admin_cidr
+ IsPrimary = local.primary_mds
+ IsSecondary = local.secondary_mds
+ SICKey = local.mds_SICkey_base64,
+ EnableInstanceConnect = var.enable_instance_connect
+ BootstrapScript = local.mds_bootstrap_script64
+ OsVersion = local.version_split
+ })
+}
+
+module "cme_iam_role" {
+ source = "../cme_iam_role"
+ count = local.create_iam_role ? 1 : 0
+
+ sts_roles = var.sts_roles
+ permissions = var.iam_permissions
+}
diff --git a/modules/mds/mds_userdata.yaml b/modules/mds/mds_userdata.yaml
new file mode 100755
index 0000000..45aee81
--- /dev/null
+++ b/modules/mds/mds_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py sicKey=\"${SICKey}\" installationType=\"mds\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"mds\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" primary=\"${IsPrimary}\" secondary=\"${IsSecondary}\" adminSubnet=\"${AdminSubnet}\" bootstrapScript64=\"${BootstrapScript}\"
\ No newline at end of file
diff --git a/modules/mds/output.tf b/modules/mds/output.tf
new file mode 100755
index 0000000..c1d3783
--- /dev/null
+++ b/modules/mds/output.tf
@@ -0,0 +1,13 @@
+output "Deployment" {
+ value = "Finalizing configuration may take up to 20 minutes after deployment is finished."
+}
+
+output "mds_instance_id" {
+ value = aws_instance.mds-instance.id
+}
+output "mds_instance_name" {
+ value = aws_instance.mds-instance.tags["Name"]
+}
+output "mds_instance_tags" {
+ value = aws_instance.mds-instance.tags
+}
\ No newline at end of file
diff --git a/modules/mds/variables.tf b/modules/mds/variables.tf
new file mode 100755
index 0000000..092cd6e
--- /dev/null
+++ b/modules/mds/variables.tf
@@ -0,0 +1,169 @@
+// Module: Check Point CloudGuard Network Multi-Domain Server into an existing VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "subnet_id" {
+ type = string
+ description = "To access the instance from the internet, make sure the subnet has a route to the internet"
+}
+
+// --- EC2 Instance Configuration ---
+variable "mds_name" {
+ type = string
+ description = "(Optional) The name tag of the Multi-Domain Server instance"
+ default = "Check-Point-MDS-tf"
+}
+variable "mds_instance_type" {
+ type = string
+ description = "The instance type of the Multi-Domain Server"
+ default = "m5.2xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "mds"
+ instance_type = var.mds_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Will fail if var.volume_size is less than 100
+ count = var.volume_size >= 100 ? 0 : "variable volume_size must be at least 100"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Multi-Domain Server EC2 Instance"
+ default = {}
+}
+
+// --- IAM Permissions (ignored when the installation type is not Primary Multi-Domain Server) ---
+variable "iam_permissions" {
+ type = string
+ description = "IAM role to attach to the instance profile"
+ default = "Create with read permissions"
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the instance profile. Ignored if var.iam_permissions is not set to 'Use existing'"
+ default = ""
+}
+variable "sts_roles" {
+ type = list(string)
+ description = "(Optional) The IAM role will be able to assume these STS Roles (list of ARNs). Ignored if var.iam_permissions is set to 'None' or 'Use existing'"
+ default = []
+}
+
+// --- Check Point Settings ---
+variable "mds_version" {
+ type = string
+ description = "Multi-Domain Server version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_mds_version" {
+ source = "../version_license"
+
+ chkp_type = "mds"
+ version_license = var.mds_version
+}
+variable "mds_admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "mds_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "mds_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Multi-Domain Server Settings ---
+variable "mds_hostname" {
+ type = string
+ description = "(Optional) Multi-Domain Server prompt hostname"
+ default = ""
+}
+variable "mds_SICKey" {
+ type = string
+ description = "Mandatory if deploying a Secondary Multi-Domain Server or Multi-Domain Log Server, the Secure Internal Communication key creates trusted connections between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "mds_installation_type" {
+ type = string
+ description = "Determines the Multi-Domain Server installation type"
+ default = "Primary Multi-Domain Server"
+}
+variable "admin_cidr" {
+ type = string
+ description = "(CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Multi-Domain Server"
+ default = "0.0.0.0/0"
+}
+variable "gateway_addresses" {
+ type = string
+ description = "(CIDR) Allow gateways only from this network to communicate with the Multi-Domain Server"
+ default = "0.0.0.0/0"
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "mds_bootstrap_script" {
+ type = string
+ description = "(Optional) Semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/mds/versions.tf b/modules/mds/versions.tf
new file mode 100755
index 0000000..c138bbb
--- /dev/null
+++ b/modules/mds/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
diff --git a/modules/common/permissive_sg/main.tf b/modules/permissive_sg/main.tf
similarity index 100%
rename from modules/common/permissive_sg/main.tf
rename to modules/permissive_sg/main.tf
diff --git a/modules/common/permissive_sg/output.tf b/modules/permissive_sg/output.tf
similarity index 100%
rename from modules/common/permissive_sg/output.tf
rename to modules/permissive_sg/output.tf
diff --git a/modules/common/permissive_sg/variables.tf b/modules/permissive_sg/variables.tf
similarity index 100%
rename from modules/common/permissive_sg/variables.tf
rename to modules/permissive_sg/variables.tf
diff --git a/modules/standalone/README.md b/modules/standalone/README.md
new file mode 100755
index 0000000..7b59914
--- /dev/null
+++ b/modules/standalone/README.md
@@ -0,0 +1,110 @@
+# Check Point CloudGuard Network Security Management Server & Security Gateway (Standalone) Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Gateway & Management (Standalone) instance into an existing VPC.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html) - conditional creation
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html) - conditional creation
+
+
+This solution uses the following modules:
+- amis
+
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/standalone"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ public_subnet_id = "subnet-123456"
+ private_subnet_id = "subnet-345678"
+ private_route_table = "rtb-12345678"
+
+ // --- EC2 Instance Configuration ---
+ standalone_name = "Check-Point-Standalone-tf"
+ standalone_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- Check Point Settings ---
+ standalone_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ standalone_password_hash = ""
+ standalone_maintenance_mode_password_hash = ""
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ standalone_hostname = "standalone-tf"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ standalone_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+ admin_cidr = "0.0.0.0/0"
+ gateway_addresses = "0.0.0.0/0"
+}
+ ```
+
+- Conditional creation
+ - To create an Elastic IP and associate it to the Standalone instance:
+ ```
+ allocate_and_associate_eip = true
+ ```
+ - To create route from '0.0.0.0/0' to the Standalone instance, please provide route table:
+ ```
+ private_route_table = "rtb-12345678"
+ ```
+
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------|
+| vpc_id | The VPC ID in which to deploy | string | |
+| public_subnet_id | Public subnet for Security Gateway & Management (Standalone) | string | |
+| private_subnet_id | Private subnet for Security Gateway & Management (Standalone) | string | |
+| private_route_table | Sets `0.0.0.0/0` route in the specified route table (e.g., rtb-12a34567) | string | |
+| standalone_name | (Optional) Name tag of the Standalone instance | string | **Default:** Check-Point-Standalone-tf |
+| standalone_instance_type | Instance type of the Standalone instance | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | EC2 Key Pair name to allow SSH access | string | |
+| allocate_and_associate_eip | Allocates and associates an Elastic IP | bool | true/false
**Default:** true |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| volume_encryption | KMS or CMK key identifier (e.g., alias/aws/ebs) | string | **Default:** alias/aws/ebs |
+| enable_instance_connect | Enable SSH connection over AWS web console | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevent accidental termination | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Deploy instance with metadata v2 token required | bool | true/false
**Default:** true |
+| instance_tags | (Optional) Map of tags as key-value pairs | map(string) | |
+| standalone_version | Standalone version and license | string | - R81.10-BYOL
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set admin shell for advanced configurations | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| standalone_password_hash | (Optional) Admin user's password hash | string | |
+| resources_tag_name | (Optional) Name tag prefix for resources | string | |
+| standalone_hostname | (Optional) Standalone instance prompt hostname | string | |
+| allow_upload_download | Automatically download Blade Contracts and other data | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point-specific CloudWatch metrics | bool | true/false
**Default:** false |
+| standalone_bootstrap_script | (Optional) Semicolon-separated commands to run during initial boot | string | |
+| primary_ntp | (Optional) IPv4 address of the primary Network Time Protocol server | string | **Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) IPv4 address of the secondary Network Time Protocol server | string | **Default:** 0.pool.ntp.org |
+| admin_cidr | CIDR for allowing access to Management Server | string | **Default:** 0.0.0.0/0 |
+| gateway_addresses | CIDR for allowing gateway access to Management Server | string | **Default:** 0.0.0.0/0 |
+| standalone_maintenance_mode_password_hash | (Optional) Admin user's password hash for maintenance mode | string | |
diff --git a/modules/standalone/locals.tf b/modules/standalone/locals.tf
new file mode 100755
index 0000000..6e438e8
--- /dev/null
+++ b/modules/standalone/locals.tf
@@ -0,0 +1,41 @@
+locals {
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ enable_cloudwatch_policy = var.enable_cloudwatch ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_cidr_range = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$"
+ // Will fail if var.admin_subnet or var.gateway_addresses are invalid
+ mgmt_subnet_regex_result = regex(local.regex_valid_cidr_range, var.admin_cidr) == var.admin_cidr ? 0 : "var.admin_subnet must be a valid CIDR range"
+ gw_addr_regex_result = regex(local.regex_valid_cidr_range, var.gateway_addresses) == var.gateway_addresses ? 0 : "var.gateway_addresses must be a valid CIDR range"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ regex_valid_standalone_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.standalone_password_hash is invalid
+ regex_standalone_password_hash = regex(local.regex_valid_standalone_password_hash, var.standalone_password_hash) == var.standalone_password_hash ? 0 : "Variable [standalone_password_hash] must be a valid password hash"
+ regex_maintenance_mode_password_hash = regex(local.regex_valid_standalone_password_hash, var.standalone_maintenance_mode_password_hash) == var.standalone_maintenance_mode_password_hash ? 0 : "Variable [standalone_maintenance_mode_password_hash] must be a valid password hash"
+
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.standalone_version), 0)
+
+ standalone_bootstrap_script64 = base64encode(var.standalone_bootstrap_script)
+ standalone_password_hash_base64 = base64encode(var.standalone_password_hash)
+ maintenance_mode_password_hash_base64 = base64encode(var.standalone_maintenance_mode_password_hash)
+}
\ No newline at end of file
diff --git a/modules/standalone/main.tf b/modules/standalone/main.tf
new file mode 100755
index 0000000..8e66906
--- /dev/null
+++ b/modules/standalone/main.tf
@@ -0,0 +1,140 @@
+module "amis" {
+ source = "../amis"
+
+ version_license = var.standalone_version
+ chkp_type = "standalone"
+}
+
+module "common_permissive_sg" {
+ source = "../permissive_sg"
+
+ security_rules = var.security_rules
+ vpc_id = var.vpc_id
+ resources_tag_name = var.resources_tag_name
+ gateway_name = var.standalone_name
+}
+
+resource "aws_iam_instance_profile" "standalone_instance_profile" {
+ count = local.enable_cloudwatch_policy
+ path = "/"
+ role = aws_iam_role.standalone_iam_role[count.index].name
+}
+
+resource "aws_iam_role" "standalone_iam_role" {
+ count = local.enable_cloudwatch_policy
+ assume_role_policy = data.aws_iam_policy_document.standalone_role_assume_policy_document.json
+ path = "/"
+}
+
+data "aws_iam_policy_document" "standalone_role_assume_policy_document" {
+ version = "2012-10-17"
+ statement {
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+ principals {
+ type = "Service"
+ identifiers = ["ec2.amazonaws.com"]
+ }
+ }
+}
+
+module "attach_cloudwatch_policy" {
+ source = "../cloudwatch_policy"
+ count = local.enable_cloudwatch_policy
+ role = aws_iam_role.standalone_iam_role[count.index].name
+ tag_name = var.resources_tag_name != "" ? var.resources_tag_name : var.standalone_name
+}
+resource "aws_network_interface" "public_eni" {
+ subnet_id = var.public_subnet_id
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "eth0"
+ source_dest_check = false
+ tags = {
+ Name = format("%s-external-eni", var.resources_tag_name != "" ? var.resources_tag_name : var.standalone_name) }
+}
+resource "aws_network_interface" "private_eni" {
+ subnet_id = var.private_subnet_id
+ security_groups = [module.common_permissive_sg.permissive_sg_id]
+ description = "eth1"
+ source_dest_check = false
+ tags = {
+ Name = format("%s-internal-eni", var.resources_tag_name != "" ? var.resources_tag_name : var.standalone_name) }
+}
+
+module "common_eip" {
+ source = "../elastic_ip"
+
+ allocate_and_associate_eip = var.allocate_and_associate_eip
+ external_eni_id = aws_network_interface.public_eni.id
+ private_ip_address = aws_network_interface.public_eni.private_ip
+}
+
+module "common_internal_default_route" {
+ source = "../internal_default_route"
+
+ private_route_table = var.private_route_table
+ internal_eni_id = aws_network_interface.private_eni.id
+}
+
+resource "aws_launch_template" "standalone_launch_template" {
+ instance_type = var.standalone_instance_type
+ key_name = var.key_name
+ image_id = module.amis.ami_id
+ description = "Initial launch template version"
+
+ iam_instance_profile {
+ name = (local.enable_cloudwatch_policy == 1 ? aws_iam_instance_profile.standalone_instance_profile[0].id : "")
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.public_eni.id
+ device_index = 0
+ }
+
+ metadata_options {
+ http_tokens = var.metadata_imdsv2_required ? "required" : "optional"
+ }
+
+ network_interfaces {
+ network_interface_id = aws_network_interface.private_eni.id
+ device_index = 1
+ }
+}
+
+resource "aws_instance" "standalone-instance" {
+ launch_template {
+ id = aws_launch_template.standalone_launch_template.id
+ version = "$Latest"
+ }
+
+ disable_api_termination = var.disable_instance_termination
+
+ tags = merge({
+ Name = var.standalone_name
+ }, var.instance_tags)
+
+ ebs_block_device {
+ device_name = "/dev/xvda"
+ volume_type = "gp2"
+ volume_size = var.volume_size
+ encrypted = local.volume_encryption_condition
+ kms_key_id = local.volume_encryption_condition ? var.volume_encryption : ""
+ }
+
+ user_data = templatefile("${path.module}/standalone_userdata.yaml", {
+ // script's arguments
+ Hostname = var.standalone_hostname,
+ PasswordHash = local.standalone_password_hash_base64,
+ MaintenanceModePassword = local.maintenance_mode_password_hash_base64,
+ AllowUploadDownload = var.allow_upload_download,
+ EnableCloudWatch = var.enable_cloudwatch,
+ NTPPrimary = var.primary_ntp,
+ NTPSecondary = var.secondary_ntp,
+ Shell = var.admin_shell,
+ AdminSubnet = var.admin_cidr,
+ EnableInstanceConnect = var.enable_instance_connect,
+ StandaloneBootstrapScript = local.standalone_bootstrap_script64
+ AllocateElasticIP = var.allocate_and_associate_eip
+ OsVersion = local.version_split
+ })
+}
\ No newline at end of file
diff --git a/modules/standalone/output.tf b/modules/standalone/output.tf
new file mode 100755
index 0000000..5a46d0f
--- /dev/null
+++ b/modules/standalone/output.tf
@@ -0,0 +1,15 @@
+output "standalone_instance_id" {
+ value = aws_instance.standalone-instance.id
+}
+output "standalone_instance_name" {
+ value = aws_instance.standalone-instance.tags["Name"]
+}
+output "standalone_public_ip" {
+ value = aws_instance.standalone-instance.public_ip
+}
+output "standalone_ssh" {
+ value = format("ssh -i %s admin@%s", var.key_name, aws_instance.standalone-instance.public_ip)
+}
+output "standalone_url" {
+ value = format("https://%s", aws_instance.standalone-instance.public_ip)
+}
\ No newline at end of file
diff --git a/modules/standalone/standalone_userdata.yaml b/modules/standalone/standalone_userdata.yaml
new file mode 100755
index 0000000..aeed1ca
--- /dev/null
+++ b/modules/standalone/standalone_userdata.yaml
@@ -0,0 +1,4 @@
+#cloud-config
+runcmd:
+ - |
+ python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" installationType=\"standalone\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.2\" templateName=\"standalone\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" hostName=\"${Hostname }\" ntpPrimary=\"${NTPPrimary}\" ntpSecondary=\"${NTPSecondary}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" adminSubnet=\"${AdminSubnet}\" allocatePublicAddress=\"${AllocateElasticIP}\" bootstrapScript64=\"${StandaloneBootstrapScript}\"
\ No newline at end of file
diff --git a/modules/standalone/variables.tf b/modules/standalone/variables.tf
new file mode 100755
index 0000000..4edda26
--- /dev/null
+++ b/modules/standalone/variables.tf
@@ -0,0 +1,166 @@
+// Module: Check Point CloudGuard Network Security Gateway & Management (Standalone) instance into an existing VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "public_subnet_id" {
+ type = string
+ description = "The public subnet of the Security Gateway & Management (Standalone)"
+}
+variable "private_subnet_id" {
+ type = string
+ description = "The private subnet of the Security Gateway & Management (Standalone)"
+}
+variable "private_route_table" {
+ type = string
+ description = "Sets '0.0.0.0/0' route to the Security Gateway & Management (Standalone) instance in the specified route table (e.g. rtb-12a34567)"
+ default= ""
+}
+
+// --- EC2 Instance Configuration ---
+variable "standalone_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway & Management (Standalone) instance"
+ default = "Check-Point-Standalone-tf"
+}
+variable "standalone_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateway & Management (Standalone) instance"
+ default = "c5.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "standalone"
+ instance_type = var.standalone_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "allocate_and_associate_eip" {
+ type = bool
+ description = "If set to true, an elastic IP will be allocated and associated with the launched instance"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Standalone EC2 Instance"
+ default = {}
+}
+
+// --- Check Point Settings ---
+variable "standalone_version" {
+ type = string
+ description = "Security Gateway & Management (Standalone) version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_standalone_version" {
+ source = "../version_license"
+
+ chkp_type = "standalone"
+ version_license = var.standalone_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "standalone_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "standalone_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) The name tag of the resources"
+ default = ""
+}
+variable "standalone_hostname" {
+ type = string
+ description = "(Optional) Security Gateway & Management (Standalone) prompt hostname"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "standalone_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "admin_cidr" {
+ type = string
+ description = "(CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Management Server"
+ default = "0.0.0.0/0"
+}
+variable "gateway_addresses" {
+ type = string
+ description = "(CIDR) Allow gateways only from this network to communicate with the Management Server"
+ default = "0.0.0.0/0"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/standalone/versions.tf b/modules/standalone/versions.tf
new file mode 100755
index 0000000..c138bbb
--- /dev/null
+++ b/modules/standalone/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
diff --git a/modules/standalone_master/README.md b/modules/standalone_master/README.md
new file mode 100755
index 0000000..bb47b10
--- /dev/null
+++ b/modules/standalone_master/README.md
@@ -0,0 +1,142 @@
+# Check Point CloudGuard Network Security Management Server & Security Gateway (Standalone) Master Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Gateway & Management (Standalone) instance into a new VPC.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [VPC](https://www.terraform.io/docs/providers/aws/r/vpc.html)
+* [Security group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [Route](https://www.terraform.io/docs/providers/aws/r/route.html)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html) - conditional creation
+
+This solution uses the following modules:
+- standalone
+- amis
+- vpc
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+- Create or modify the deployment:
+ - Due to terraform limitation, the apply command is:
+ ```
+ terraform apply -target=module.{module_name}.aws_route_table.private_subnet_rtb -auto-approve && terraform apply
+ ```
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/standalone_master"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ }
+ private_subnets_map = {
+ "us-east-1a" = 2
+ }
+ subnets_bit_length = 8
+
+ // --- EC2 Instance Configuration ---
+ standalone_name = "Check-Point-Standalone-tf"
+ standalone_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+
+ // --- Check Point Settings ---
+ standalone_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ standalone_password_hash = ""
+ standalone_maintenance_mode_password_hash = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ standalone_hostname = "standalone-tf"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ standalone_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+ admin_cidr = "0.0.0.0/0"
+ gateway_addresses = "0.0.0.0/0"
+}
+ ```
+
+- Conditional creation
+ - To create an Elastic IP and associate it to the Standalone instance:
+ ```
+ allocate_and_associate_eip = true
+ ```
+
+
+
+
+## Inputs
+| Name | Description | Type | Allowed Values |
+|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|--------------------------------------------------------------------------------------------------------------------|
+| vpc_cidr | The CIDR block of the VPC | string | |
+| public_subnets_map | A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair. | map | |
+| private_subnets_map | A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair. | map | |
+| subnets_bit_length | Number of additional bits with which to extend the VPC CIDR | number | |
+| standalone_name | The name tag of the Security Gateway & Management (Standalone) instance | string |**Default:** Check-Point-Standalone-tf |
+| standalone_instance_type | The instance type of the Security Gateway & Management (Standalone) instance | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| allocate_and_associate_eip | Allocate and associate an Elastic IP with the launched instance | bool | true/false
**Default:** true |
+| volume_size | Root volume size (GB) | number |**Default:** 100 |
+| volume_encryption | KMS or CMK key Identifier | string |**Default:** alias/aws/ebs |
+| enable_instance_connect | Enable SSH connection over AWS web console | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevent accidental termination of the instance | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Deploy instance with metadata v2 token required | bool | true/false
**Default:** true |
+| instance_tags | A map of tags as key=value pairs. | map(string) |**Default:** {} |
+| standalone_version | Security Gateway & Management (Standalone) version and license | string | - R81.20-BYOL
- R82-PAYG-NGTP
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command-line configuration | string | - /etc/cli.sh
- /bin/bash
**Default:** /etc/cli.sh |
+| standalone_password_hash | Admin user's password hash | string | |
+| resources_tag_name | (Optional) | string | |
+| standalone_hostname | Security Gateway & Management (Standalone) prompt hostname | string | |
+| allow_upload_download | Automatically download Blade Contracts and other important data | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point-specific CloudWatch metrics | bool | true/false
**Default:** false |
+| standalone_bootstrap_script | Semicolon (;) separated commands to run on the initial boot | string | |
+| primary_ntp | IPv4 address of Network Time Protocol primary server | string |**Default:** 169.254.169.123 |
+| secondary_ntp | IPv4 address of Network Time Protocol secondary server | string |**Default:** 0.pool.ntp.org |
+| admin_cidr | Allow web, SSH, and graphical clients from this network to communicate with the Management Server | string |**Default:** 0.0.0.0/0 |
+| gateway_addresses | Allow gateways only from this network to communicate with the Management Server | string |**Default:** 0.0.0.0/0 |
+| standalone_maintenance_mode_password_hash | Maintenance-mode password hash | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|------------------------------|------------------------------------------------------------------------------|
+| vpc_id | The id of the deployed vpc |
+| internal_rtb_id | The internal route table id |
+| vpc_public_subnets_ids_list | A list of the public subnets ids |
+| vpc_private_subnets_ids_list | A list of the private subnets ids |
+| standalone_instance_id | The deployed Security Gateway & Management (Standalone) AWS instance id |
+| standalone_instance_name | The deployed Security Gateway & Management (Standalone) AWS instance name |
+| standalone_public_ip | The deployed Security Gateway & Management (Standalone) AWS public address |
+| standalone_ssh | SSH command to the Security Gateway & Management (Standalone) |
+| standalone_url | URL to the portal of the deployed Security Gateway & Management (Standalone) |
diff --git a/modules/standalone_master/locals.tf b/modules/standalone_master/locals.tf
new file mode 100755
index 0000000..e2e6ab4
--- /dev/null
+++ b/modules/standalone_master/locals.tf
@@ -0,0 +1,35 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_cidr_range = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$"
+ // Will fail if var.admin_subnet or var.gateway_addresses are invalid
+ mgmt_subnet_regex_result = regex(local.regex_valid_cidr_range, var.admin_cidr) == var.admin_cidr ? 0 : "var.admin_subnet must be a valid CIDR range"
+ gw_addr_regex_result = regex(local.regex_valid_cidr_range, var.gateway_addresses) == var.gateway_addresses ? 0 : "var.gateway_addresses must be a valid CIDR range"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ regex_valid_standalone_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.standalone_password_hash is invalid
+ regex_standalone_password_hash = regex(local.regex_valid_standalone_password_hash, var.standalone_password_hash) == var.standalone_password_hash ? 0 : "Variable [standalone_password_hash] must be a valid password hash"
+ regex_maintenance_mode_password_hash = regex(local.regex_valid_standalone_password_hash, var.standalone_maintenance_mode_password_hash) == var.standalone_maintenance_mode_password_hash ? 0 : "Variable [standalone_maintenance_mode_password_hash] must be a valid password hash"
+}
\ No newline at end of file
diff --git a/modules/standalone_master/main.tf b/modules/standalone_master/main.tf
new file mode 100755
index 0000000..8594317
--- /dev/null
+++ b/modules/standalone_master/main.tf
@@ -0,0 +1,56 @@
+
+// --- VPC ---
+module "launch_vpc" {
+ source = "../vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = var.private_subnets_map
+ subnets_bit_length = var.subnets_bit_length
+}
+
+resource "aws_route_table" "private_subnet_rtb" {
+ depends_on = [module.launch_vpc]
+ vpc_id = module.launch_vpc.vpc_id
+ tags = {
+ Name = "Private Subnets Route Table"
+ }
+}
+resource "aws_route_table_association" "private_rtb_to_private_subnets" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ route_table_id = aws_route_table.private_subnet_rtb.id
+ subnet_id = module.launch_vpc.private_subnets_ids_list[0]
+}
+
+module "launch_standalone_into_vpc" {
+ source = "../standalone"
+
+ security_rules = var.security_rules
+ vpc_id = module.launch_vpc.vpc_id
+ public_subnet_id = module.launch_vpc.public_subnets_ids_list[0]
+ private_subnet_id = module.launch_vpc.private_subnets_ids_list[0]
+ private_route_table = aws_route_table.private_subnet_rtb.id
+ resources_tag_name = var.resources_tag_name
+ standalone_name = var.standalone_name
+ standalone_instance_type = var.standalone_instance_type
+ key_name = var.key_name
+ allocate_and_associate_eip = var.allocate_and_associate_eip
+ volume_size = var.volume_size
+ volume_encryption = var.volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ instance_tags = var.instance_tags
+ standalone_version = var.standalone_version
+ admin_shell = var.admin_shell
+ standalone_password_hash = var.standalone_password_hash
+ standalone_maintenance_mode_password_hash = var.standalone_maintenance_mode_password_hash
+ standalone_hostname = var.standalone_hostname
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ standalone_bootstrap_script = var.standalone_bootstrap_script
+ primary_ntp = var.primary_ntp
+ secondary_ntp = var.secondary_ntp
+ admin_cidr = var.admin_cidr
+ gateway_addresses = var.gateway_addresses
+}
diff --git a/modules/standalone_master/output.tf b/modules/standalone_master/output.tf
new file mode 100755
index 0000000..11d557b
--- /dev/null
+++ b/modules/standalone_master/output.tf
@@ -0,0 +1,27 @@
+output "vpc_id" {
+ value = module.launch_vpc.vpc_id
+}
+output "internal_rtb_id" {
+ value = aws_route_table.private_subnet_rtb.id
+}
+output "vpc_public_subnets_ids_list" {
+ value = module.launch_vpc.public_subnets_ids_list
+}
+output "vpc_private_subnets_ids_list" {
+ value = module.launch_vpc.private_subnets_ids_list
+}
+output "standalone_instance_id" {
+ value = module.launch_standalone_into_vpc.standalone_instance_id
+}
+output "standalone_instance_name" {
+ value = module.launch_standalone_into_vpc.standalone_instance_name
+}
+output "standalone_public_ip" {
+ value = module.launch_standalone_into_vpc.standalone_public_ip
+}
+output "standalone_ssh" {
+ value = module.launch_standalone_into_vpc.standalone_ssh
+}
+output "standalone_url" {
+ value = module.launch_standalone_into_vpc.standalone_url
+}
\ No newline at end of file
diff --git a/modules/standalone_master/variables.tf b/modules/standalone_master/variables.tf
new file mode 100755
index 0000000..60a9e77
--- /dev/null
+++ b/modules/standalone_master/variables.tf
@@ -0,0 +1,168 @@
+// Module: Check Point CloudGuard Network Security Gateway & Management (Standalone) instance into a new VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair. (e.g. {\"us-east-1a\" = 1} ) "
+}
+variable "private_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair. (e.g. {\"us-east-1a\" = 2} ) "
+
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+
+// --- EC2 Instance Configuration ---
+variable "standalone_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway & Management (Standalone) instance"
+ default = "Check-Point-Standalone-tf"
+}
+variable "standalone_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateway & Management (Standalone) instance"
+ default = "c5.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "standalone"
+ instance_type = var.standalone_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "allocate_and_associate_eip" {
+ type = bool
+ description = "If set to true, an elastic IP will be allocated and associated with the launched instance"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Standalone EC2 Instance"
+ default = {}
+}
+
+// --- Check Point Settings ---
+variable "standalone_version" {
+ type = string
+ description = "Gateway & Management (Standalone) version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_standalone_version" {
+ source = "../version_license"
+
+ chkp_type = "standalone"
+ version_license = var.standalone_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "standalone_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "standalone_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) The name tag of the resources"
+ default = ""
+}
+variable "standalone_hostname" {
+ type = string
+ description = "(Optional) Security Gateway & Management (Standalone) prompt hostname"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "standalone_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "admin_cidr" {
+ type = string
+ description = "(CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Management Server"
+ default = "0.0.0.0/0"
+}
+variable "gateway_addresses" {
+ type = string
+ description = "(CIDR) Allow gateways only from this network to communicate with the Management Server"
+ default = "0.0.0.0/0"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/standalone_master/versions.tf b/modules/standalone_master/versions.tf
new file mode 100755
index 0000000..a95f017
--- /dev/null
+++ b/modules/standalone_master/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/tgw_asg/README.md b/modules/tgw_asg/README.md
new file mode 100755
index 0000000..4bf1667
--- /dev/null
+++ b/modules/tgw_asg/README.md
@@ -0,0 +1,147 @@
+# Check Point CloudGuard Network Transit Gateway Auto Scaling Group Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Gateway Auto Scaling Group for Transit Gateway with an optional Management Server into an existing VPC.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [CloudWatch Metric Alarm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html)
+* [Launch template](https://www.terraform.io/docs/providers/aws/r/launch_template.html)
+* [Auto Scaling Group](https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [CloudGuard Network for AWS Transit Gateway R80.10 and Higher Deployment Guide](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_AWS_Transit_Gateway/Content/Topics-AWS-TGW-R80-10-AG/Introduction.htm) for additional information
+
+This solution uses the following modules:
+- autoscale
+- management
+- cme_iam_role
+
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/tgw_asg"
+ version = "1.0.2"
+
+ // --- Network Configuration ---
+ vpc_id = "vpc-12345678"
+ gateways_subnets = ["subnet-123b5678", "subnet-123a4567"]
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+
+ // --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = "Check-Point-gateway"
+ gateway_instance_type = "c5.xlarge"
+ gateways_min_group_size = 2
+ gateways_max_group_size = 8
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ enable_cloudwatch = true
+ asn = "6500"
+
+ // --- Check Point CloudGuard Network Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ management_permissions = "Create with read-write permissions"
+ management_predefined_role = ""
+ gateways_blades = true
+ admin_cidr = "0.0.0.0/0"
+ gateways_addresses = "0.0.0.0/0"
+ gateway_management = "Locally managed"
+
+ // --- Automatic Provisioning with Security Management Server Settings ---
+ control_gateway_over_public_or_private_address = "private"
+ management_server = "management-server"
+ configuration_template = "template-name"
+ ```
+
+ - Conditional creation
+ - To create a Security Management server with IAM Role:
+ ```
+ management_permissions = "Create with read permissions" | "Create with read-write permissions" | "Create with assume role permissions (specify an STS role ARN)"
+ ```
+ - To enable cloudwatch for ASG:
+ ```
+ enable_cloudwatch = true
+ ```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To deploy Security Management Server:
+ ```
+ management_deploy = true
+ }
+ ```
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------|
+| vpc_id | Select an existing VPC | string | |
+| gateways_subnets | Select at least 2 public subnets in the VPC. If deploying a Security Management Server, it will be in the first subnet | list(string) | |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevent accidental termination of an instance | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Deploy instance with metadata v2 token required | bool | true/false
**Default:** true |
+| allow_upload_download | Automatically download Blade Contracts and other data | bool | true/false
**Default:** true |
+| gateway_name | (Optional) Name tag of the Security Gateway instances | string | **Default:** Check-Point-Gateway |
+| gateway_instance_type | Instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| gateways_min_group_size | Minimum number of Security Gateways | number | **Default:** 2 |
+| gateways_max_group_size | Maximum number of Security Gateways | number | **Default:** 10 |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R82-PAYG-NGTP
**Default:** R81.20-BYOL |
+| gateway_password_hash | (Optional) Admin user's password hash | string | |
+| gateway_SIC_Key | Secure Internal Communication key | string | **Default:** "12345678" |
+| enable_cloudwatch | Report Check Point-specific CloudWatch metrics | bool | true/false
**Default:** false |
+| asn | Organization Autonomous System Number (ASN) identifying the routing domain | string | **Default:** 6500 |
+| management_deploy | Set to 'false' to use an existing Security Management Server | bool | true/false
**Default:** true |
+| management_instance_type | Instance type of the Security Management Server | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
+| management_version | License for the Security Management Server | string | - R81.20-BYOL
- R82-BYOL
**Default:** R81.20-BYOL |
+| management_password_hash | (Optional) Admin user's password hash | string | |
+| management_permissions | IAM role for the instance profile | string | - None
- Use existing
- Create with read-write permissions
**Default:** Create with read-write permissions |
+| gateways_blades | Enable the Intrusion Prevention System, Application Control, Anti-Virus, and Anti-Bot Blades | bool | true/false
**Default:** true |
+| admin_cidr | Allow web, SSH, and graphical clients only from this network | string | |
+| gateway_addresses | Allow gateways only from this network | string | |
+| gateway_management | Select 'Over the internet' if gateways aren't accessed via private IP | string | - Locally managed
- Over the internet
**Default:** Locally managed |
+| control_gateway_over_public_or_private_address | Determines if gateways use private or public address | string | - private
- public
**Default:** private |
+| management_server | (Optional) Name representing the Security Management Server | string |
**Default:** management-server |
+| configuration_template | (Optional) Security Gateway configuration template | string |
**Default:** TGW-ASG-configuration |
+| gateway_maintenance_mode_password_hash | Maintenance-mode password hash | string | |
+| management_maintenance_mode_password_hash | Maintenance-mode password hash for Security Management Server | string | |
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| management_instance_name | The deployed Security Management AWS instance name |
+| management_public_ip | The deployed Security Management Server AWS public ip |
+| management_url | URL to the portal of the deployed Security Management Server |
+| autoscaling_group_name | The name of the deployed AutoScaling Group |
+| configuration_template | The name that represents the configuration template. Configurations required to automatically provision the Gateways in the Auto Scaling Group, such as what Security Policy to install and which Blades to enable, will be placed under this template name |
+| controller_name | The name that represents the controller. Configurations required to connect to your AWS environment, such as credentials and regions, will be placed under this controller name |
+
diff --git a/modules/tgw_asg/locals.tf b/modules/tgw_asg/locals.tf
new file mode 100755
index 0000000..7ecd5cf
--- /dev/null
+++ b/modules/tgw_asg/locals.tf
@@ -0,0 +1,64 @@
+locals {
+ permissions_allowed_values = [
+ "None (configure later)",
+ "Use existing (specify an existing IAM role name)",
+ "Create with assume role permissions (specify an STS role ARN)",
+ "Create with read permissions",
+ "Create with read-write permissions"]
+ // Will fail if var.management_permissions is invalid
+ validate_permissions = index(local.permissions_allowed_values, var.management_permissions)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ control_over_public_or_private_allowed_values = [
+ "public",
+ "private"]
+ // will fail if [var.control_gateway_over_public_or_private_address] is invalid:
+ validate_control_over_public_or_private = index(local.control_over_public_or_private_allowed_values, var.control_gateway_over_public_or_private_address)
+
+ gateway_management_allowed_values = [
+ "Locally managed",
+ "Over the internet"]
+ // will fail if [var.gateway_management] is invalid:
+ validate_gateway_management = index(local.gateway_management_allowed_values, var.gateway_management)
+
+ regex_valid_management_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.management_password_hash is invalid
+ regex_management_password_hash = regex(local.regex_valid_management_password_hash, var.management_password_hash) == var.management_password_hash ? 0 : "Variable [management_password_hash] must be a valid password hash"
+ regex_management_maintenance_mode_password_hash = regex(local.regex_valid_management_password_hash, var.management_maintenance_mode_password_hash) == var.management_maintenance_mode_password_hash ? 0 : "Variable [management_maintenance_mode_password_hash] must be a valid password hash"
+
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+
+ regex_valid_asn = "^[0-9]+$"
+ // Will fail if var.asn is invalid
+ regex_asn = regex(local.regex_valid_asn, var.asn) == var.asn ? 0 : "Variable [asn] must be a valid asn"
+
+ regex_valid_admin_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.admin_cidr is invalid
+ regex_admin_cidr = regex(local.regex_valid_admin_cidr, var.admin_cidr) == var.admin_cidr ? 0 : "Variable [admin_cidr] must be a valid CIDR"
+
+ regex_valid_gateways_addresses = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.gateways_addresses is invalid
+ regex_gateways_addresses = regex(local.regex_valid_gateways_addresses, var.gateways_addresses) == var.gateways_addresses ? 0 : "Variable [gateways_addresses] must be a valid gateways addresses"
+
+ regex_valid_management_server = "^[0-9a-zA-Z-._]+$"
+ // Will fail if var.management_server is invalid
+ regex_management_server = regex(local.regex_valid_management_server, var.management_server) == var.management_server ? 0 : "Variable [management_server] can not be an empty string"
+
+ regex_valid_configuration_template = "^[0-9a-zA-Z-._]+$"
+ // Will fail if var.configuration_template is invalid
+ regex_configuration_template = regex(local.regex_valid_configuration_template, var.configuration_template) == var.configuration_template ? 0 : "Variable [configuration_template] can not be an empty string"
+
+ deploy_management_condition = var.management_deploy == true
+}
\ No newline at end of file
diff --git a/modules/tgw_asg/main.tf b/modules/tgw_asg/main.tf
new file mode 100755
index 0000000..27acf00
--- /dev/null
+++ b/modules/tgw_asg/main.tf
@@ -0,0 +1,54 @@
+module "autoscale" {
+ source = "../autoscale"
+
+
+ vpc_id = var.vpc_id
+ subnet_ids = var.gateways_subnets
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ enable_volume_encryption = var.enable_volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ minimum_group_size = var.gateways_min_group_size
+ maximum_group_size = var.gateways_max_group_size
+ gateway_version = var.gateway_version
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ gateway_SICKey = var.gateway_SICKey
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = "echo -e '\nStarting Bootstrap script\n'; echo 'Adding tgw identifier to cloud-version'; cv_path='/etc/cloud-version'\n if test -f \"$cv_path\"; then sed -i '/template_name/c\\template_name: autoscale_tgw' /etc/cloud-version; fi; cv_json_path='/etc/cloud-version.json'\n cv_json_path_tmp='/etc/cloud-version-tmp.json'\n if test -f \"$cv_json_path\"; then cat \"$cv_json_path\" | jq '.template_name = \"'\"autoscale_tgw\"'\"' > \"$cv_json_path_tmp\"; mv \"$cv_json_path_tmp\" \"$cv_json_path\"; fi; echo 'Setting ASN to: ${var.asn}'; clish -c 'set as ${var.asn}' -s; echo -e '\nFinished Bootstrap script\n'"
+ gateways_provision_address_type = var.control_gateway_over_public_or_private_address
+ management_server = var.management_server
+ configuration_template = var.configuration_template
+}
+
+data "aws_region" "current"{}
+
+module "management" {
+
+ count = local.deploy_management_condition ? 1 : 0
+ source = "../management"
+
+ vpc_id = var.vpc_id
+ subnet_id = var.gateways_subnets[0]
+ management_name = var.management_server
+ management_instance_type = var.management_instance_type
+ key_name = var.key_name
+ allocate_and_associate_eip = true
+ volume_encryption = var.enable_volume_encryption ? "alias/aws/ebs" : ""
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ iam_permissions = var.management_permissions
+ predefined_role = var.management_predefined_role
+ management_version = var.management_version
+ management_password_hash = var.management_password_hash
+ management_maintenance_mode_password_hash = var.management_maintenance_mode_password_hash
+ allow_upload_download = var.allow_upload_download
+ admin_cidr = var.admin_cidr
+ gateway_addresses = var.gateways_addresses
+ gateway_management = var.gateway_management
+ management_bootstrap_script = "echo -e '\nStarting Bootstrap script\n'; echo 'Adding tgw identifier to cloud-version'; cv_path='/etc/cloud-version'\n if test -f \"$cv_path\"; then sed -i '/template_name/c\\template_name: management_tgw_asg' /etc/cloud-version; fi; cv_json_path='/etc/cloud-version.json'\n cv_json_path_tmp='/etc/cloud-version-tmp.json'\n if test -f \"$cv_json_path\"; then cat \"$cv_json_path\" | jq '.template_name = \"'\"management_tgw_asg\"'\"' > \"$cv_json_path_tmp\"; mv \"$cv_json_path_tmp\" \"$cv_json_path\"; fi; echo 'Configuring VPN community: tgw-community'; [[ -d /opt/CPcme/menu/additions ]] && /opt/CPcme/menu/additions/config-community.sh \"tgw-community\" || /etc/fw/scripts/autoprovision/config-community.sh \"tgw-community\"; echo 'Setting VPN rules'; mgmt_cli -r true add access-layer name 'Inline'; mgmt_cli -r true add access-rule layer Network position 1 name 'tgw-community VPN Traffic Rule' vpn.directional.1.from 'tgw-community' vpn.directional.1.to 'tgw-community' vpn.directional.2.from 'tgw-community' vpn.directional.2.to External_clear action 'Apply Layer' inline-layer 'Inline'; mgmt_cli -r true add nat-rule package standard position bottom install-on 'Policy Targets' original-source All_Internet translated-source All_Internet method hide; echo 'Creating CME configuration'; autoprov_cfg -f init AWS -mn ${var.management_server} -tn ${var.configuration_template} -cn tgw-controller -po Standard -otp ${var.gateway_SICKey} -r ${data.aws_region.current.name} -ver ${split("-", var.gateway_version)[0]} -iam -dt TGW; autoprov_cfg -f set controller AWS -cn tgw-controller -sv -com tgw-community; autoprov_cfg -f set template -tn ${var.configuration_template} -vpn -vd '''' -con tgw-community; ${var.gateways_blades} && autoprov_cfg -f set template -tn ${var.configuration_template} -ia -ips -appi -av -ab; echo -e '\nFinished Bootstrap script\n'"
+}
\ No newline at end of file
diff --git a/modules/tgw_asg/output.tf b/modules/tgw_asg/output.tf
new file mode 100755
index 0000000..4164a41
--- /dev/null
+++ b/modules/tgw_asg/output.tf
@@ -0,0 +1,18 @@
+output "management_instance_name" {
+ value = try(module.management[0].management_instance_name, null)
+}
+output "configuration_template" {
+ value = var.configuration_template
+}
+output "controller_name" {
+ value = "tgw-controller"
+}
+output "management_public_ip" {
+ value = try(module.management[0].management_public_ip, null)
+}
+output "management_url" {
+ value = try(module.management[0].management_url, null)
+}
+output "autoscaling_group_name" {
+ value = module.autoscale.autoscale_autoscaling_group_name
+}
diff --git a/modules/tgw_asg/variables.tf b/modules/tgw_asg/variables.tf
new file mode 100755
index 0000000..2cb87a7
--- /dev/null
+++ b/modules/tgw_asg/variables.tf
@@ -0,0 +1,193 @@
+// Module: Check Point CloudGuard Network Transit Gateway Auto Scaling Group
+// Deploy an Auto Scaling Group of CloudGuard Security Gateways for Transit Gateway with an optional Management Server into an existing VPC
+
+// --- Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "gateways_subnets" {
+ type = list(string)
+ description = "Select at least 2 external subnets in the VPC. If you choose to deploy a Security Management Server it will be deployed in the first subnet"
+}
+
+// --- General Settings ---
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+
+// --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Gateway"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_gateway_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "gateways_min_group_size" {
+ type = number
+ description = "The minimal number of Security Gateways"
+ default = 2
+}
+variable "gateways_max_group_size" {
+ type = number
+ description = "The maximal number of Security Gateways"
+ default = 10
+}
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "asn" {
+ type = string
+ description = "The organization Autonomous System Number (ASN) that identifies the routing domain for the Security Gateways"
+ default = "6500"
+}
+
+// --- Check Point CloudGuard Network Security Management Server Configuration ---
+variable "management_deploy" {
+ type = bool
+ description = "Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section"
+ default = true
+}
+variable "management_instance_type" {
+ type = string
+ description = "The EC2 instance type of the Security Management Server"
+ default = "m5.xlarge"
+}
+module "validate_management_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "management"
+ instance_type = var.management_instance_type
+}
+variable "management_version" {
+ type = string
+ description = "The license to install on the Security Management Server"
+ default = "R81.20-BYOL"
+}
+module "validate_management_version" {
+ source = "../version_license"
+
+ chkp_type = "management"
+ version_license = var.management_version
+}
+variable "management_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "management_maintenance_mode_password_hash" {
+ description = "(optional) Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. For R81.10 and below the Admin user's password is used also as maintenance-mode password. (To generate a password hash use the command 'grub2-mkpasswd-pbkdf2' on Linux and paste it here)."
+ type = string
+ default = ""
+}
+variable "management_permissions" {
+ type = string
+ description = "IAM role to attach to the instance profile"
+ default = "Create with read-write permissions"
+}
+variable "management_predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the instance profile. Ignored if IAM role is not set to 'Use existing'"
+ default = ""
+}
+variable "gateways_blades" {
+ type = bool
+ description = "Turn on the Intrusion Prevention System, Application Control, Anti-Virus and Anti-Bot Blades (additional Blades can be manually turned on later)"
+ default = true
+}
+variable "admin_cidr" {
+ type = string
+ description = "Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server"
+}
+variable "gateways_addresses" {
+ type = string
+ description = "Allow gateways only from this network to communicate with the Security Management Server"
+}
+variable "gateway_management" {
+ type = string
+ description = "Select 'Over the internet' if any of the gateways you wish to manage are not directly accessed via their private IP address"
+ default = "Locally managed"
+}
+
+// --- Automatic Provisioning with Security Management Server Settings ---
+variable "control_gateway_over_public_or_private_address" {
+ type = string
+ description = "Determines if the gateways are provisioned using their private or public address"
+ default = "private"
+}
+variable "management_server" {
+ type = string
+ description = "(Optional) The name that represents the Security Management Server in the automatic provisioning configuration"
+ default = "management-server"
+}
+variable "configuration_template" {
+ type = string
+ description = "(Optional) A name of a Security Gateway configuration template in the automatic provisioning configuration"
+ default = "TGW-ASG-configuration"
+ validation {
+ condition = length(var.configuration_template) < 31
+ error_message = "The configuration_template name can not exceed 30 characters"
+ }
+}
diff --git a/modules/tgw_asg/versions.tf b/modules/tgw_asg/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/tgw_asg/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/tgw_asg_master/README.md b/modules/tgw_asg_master/README.md
new file mode 100755
index 0000000..dced05b
--- /dev/null
+++ b/modules/tgw_asg_master/README.md
@@ -0,0 +1,156 @@
+# Check Point CloudGuard Network Transit Gateway Auto Scaling Group Master Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Gateway Auto Scaling Group for Transit Gateway with an optional Management Server in a new VPC.
+
+These types of Terraform resources are supported:
+* [VPC](https://www.terraform.io/docs/providers/aws/r/vpc.html)
+* [Subnet](https://www.terraform.io/docs/providers/aws/r/subnet.html)
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [CloudWatch Metric Alarm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm)
+* [EIP](https://www.terraform.io/docs/providers/aws/r/eip.html)
+* [Launch template](https://www.terraform.io/docs/providers/aws/r/launch_template.html)
+* [Auto Scaling Group](https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [CloudGuard Network for AWS Transit Gateway R80.10 and Higher Deployment Guide](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_AWS_Transit_Gateway/Content/Topics-AWS-TGW-R80-10-AG/Introduction.htm) for additional information
+
+This solution uses the following modules:
+- tgw_asg
+- autoscale
+- management
+- cme_iam_role
+- vpc
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/tgw_asg_master"
+ version = "1.0.2"
+
+ // --- Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ "us-east-1b" = 2
+ }
+ subnets_bit_length = 8
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+
+ // --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = "Check-Point-gateway"
+ gateway_instance_type = "c5.xlarge"
+ gateways_min_group_size = 2
+ gateways_max_group_size = 8
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ enable_cloudwatch = true
+ asn = "6500"
+
+ // --- Check Point CloudGuard Network Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ management_permissions = "Create with read-write permissions"
+ management_predefined_role = ""
+ gateways_blades = true
+ admin_cidr = "0.0.0.0/0"
+ gateways_addresses = "0.0.0.0/0"
+ gateway_management = "Locally managed"
+
+ // --- Automatic Provisioning with Security Management Server Settings ---
+ control_gateway_over_public_or_private_address = "private"
+ management_server = "management-server"
+ configuration_template = "template-name"
+}
+```
+
+ - Conditional creation
+ - To create a Security Management server with IAM Role:
+```
+ management_permissions = "Create with read permissions" | "Create with read-write permissions" | "Create with assume role permissions (specify an STS role ARN)"
+```
+ - To enable cloudwatch for ASG:
+```
+ enable_cloudwatch = true
+```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To deploy Security Management Server:
+```
+ management_deploy = true
+```
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------|
+| vpc_cidr | The CIDR block of the VPC | string | |
+| public_subnets_map | Map of pairs {availability-zone = subnet-suffix-number}. Minimum 2 pairs required | map | |
+| subnets_bit_length | Additional bits to extend the VPC CIDR | number | |
+| key_name | The EC2 Key Pair name to allow SSH access | string | |
+| enable_volume_encryption | Encrypt Environment instances volume with AWS KMS key | bool | true/false
**Default:** true |
+| enable_instance_connect | Enable SSH over AWS web console ([Regions](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/)) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevent accidental termination | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Deploy instance with metadata v2 token required | bool | true/false
**Default:** true |
+| allow_upload_download | Automatically download Blade Contracts and other important data | bool | true/false
**Default:** true |
+| gateway_name | (Optional) Name tag of the Security Gateway instances | string | **Default:** Check-Point-Gateway |
+| gateway_instance_type | Instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| gateways_min_group_size | Minimum number of Security Gateways | number | **Default:** 2 |
+| gateways_max_group_size | Maximum number of Security Gateways | number | **Default:** 10 |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R82-PAYG
**Default:** R81.20-BYOL |
+| gateway_password_hash | (Optional) Admin user's password hash | string | |
+| gateway_SIC_Key | Secure Internal Communication key | string | **Default:** "12345678" |
+| enable_cloudwatch | Report Check Point-specific CloudWatch metrics | bool | true/false
**Default:** false |
+| asn | Organization Autonomous System Number (ASN) | string | **Default:** 6500 |
+| management_deploy | Deploy or use an existing Security Management Server | bool | true/false
**Default:** true |
+| management_instance_type | Instance type of the Security Management Server | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
+| management_version | License for the Security Management Server | string | - R81.10-BYOL
- R82-BYOL
**Default:** R81.20-BYOL |
+| management_password_hash | (Optional) Admin user's password hash | string | |
+| management_permissions | IAM role for the instance profile | string | - None
- Use existing
- Create with read-write permissions
**Default:** Create with read-write permissions |
+| gateways_blades | Enable Intrusion Prevention System, Application Control, and other blades | bool | true/false
**Default:** true |
+| admin_cidr | Allow web, SSH, and graphical clients only from this network | string | |
+| gateway_addresses | Allow gateways only from this network | string | |
+| gateway_management | Select 'Over the internet' for non-private IP-managed gateways | string | - Locally managed
- Over the internet
**Default:** Locally managed |
+| control_gateway_over_public_or_private_address | Use private or public address for gateways | string | - private
- public
**Default:** private |
+| management_server | (Optional) Name representing the Security Management Server | string | **Default:** management-server |
+| configuration_template | (Optional) Security Gateway configuration template | string | **Default:** TGW-ASG-configuration |
+| gateway_maintenance_mode_password_hash | Maintenance-mode password hash | string | |
+| management_maintenance_mode_password_hash | Maintenance-mode password hash for the Security Management Server | string | |
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| vpc_id | The id of the deployed vpc |
+| public_subnets_ids_list | A list of the public subnets ids |
+| management_instance_name | The deployed Security Management AWS instance name |
+| management_public_ip | The deployed Security Management Server AWS public ip |
+| management_url | URL to the portal of the deployed Security Management Server |
+| autoscaling_group_name | The name of the deployed AutoScaling Group |
+| configuration_template | The name that represents the configuration template. Configurations required to automatically provision the Gateways in the Auto Scaling Group, such as what Security Policy to install and which Blades to enable, will be placed under this template name |
+| controller_name | The name that represents the controller. Configurations required to connect to your AWS environment, such as credentials and regions, will be placed under this controller name |
diff --git a/modules/tgw_asg_master/locals.tf b/modules/tgw_asg_master/locals.tf
new file mode 100755
index 0000000..467c4b4
--- /dev/null
+++ b/modules/tgw_asg_master/locals.tf
@@ -0,0 +1,66 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ permissions_allowed_values = [
+ "None (configure later)",
+ "Use existing (specify an existing IAM role name)",
+ "Create with assume role permissions (specify an STS role ARN)",
+ "Create with read permissions",
+ "Create with read-write permissions"]
+ // Will fail if var.management_permissions is invalid
+ validate_permissions = index(local.permissions_allowed_values, var.management_permissions)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ control_over_public_or_private_allowed_values = [
+ "public",
+ "private"]
+ // will fail if [var.control_gateway_over_public_or_private_address] is invalid:
+ validate_control_over_public_or_private = index(local.control_over_public_or_private_allowed_values, var.control_gateway_over_public_or_private_address)
+
+ gateway_management_allowed_values = [
+ "Locally managed",
+ "Over the internet"]
+ // will fail if [var.gateway_management] is invalid:
+ validate_gateway_management = index(local.gateway_management_allowed_values, var.gateway_management)
+
+ regex_valid_management_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.management_password_hash is invalid
+ regex_management_password_hash = regex(local.regex_valid_management_password_hash, var.management_password_hash) == var.management_password_hash ? 0 : "Variable [management_password_hash] must be a valid password hash"
+ regex_management_maintenance_mode_password_hash = regex(local.regex_valid_management_password_hash, var.management_maintenance_mode_password_hash) == var.management_maintenance_mode_password_hash ? 0 : "Variable [management_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_asn = "^[0-9]+$"
+ // Will fail if var.asn is invalid
+ regex_asn = regex(local.regex_valid_asn, var.asn) == var.asn ? 0 : "Variable [asn] must be a valid asn"
+
+ regex_valid_admin_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.admin_cidr is invalid
+ regex_admin_cidr = regex(local.regex_valid_admin_cidr, var.admin_cidr) == var.admin_cidr ? 0 : "Variable [admin_cidr] must be a valid CIDR"
+
+ regex_valid_gateways_addresses = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
+ // Will fail if var.gateways_addresses is invalid
+ regex_gateways_addresses = regex(local.regex_valid_gateways_addresses, var.gateways_addresses) == var.gateways_addresses ? 0 : "Variable [gateways_addresses] must be a valid gateways addresses"
+
+ regex_valid_management_server = "^[0-9a-zA-Z-._]+$"
+ // Will fail if var.management_server is invalid
+ regex_management_server = regex(local.regex_valid_management_server, var.management_server) == var.management_server ? 0 : "Variable [management_server] can not be an empty string"
+
+ regex_valid_configuration_template = "^[0-9a-zA-Z-._]+$"
+ // Will fail if var.configuration_template is invalid
+ regex_configuration_template = regex(local.regex_valid_configuration_template, var.configuration_template) == var.configuration_template ? 0 : "Variable [configuration_template] can not be an empty string"
+
+ deploy_management_condition = var.management_deploy == true
+}
\ No newline at end of file
diff --git a/modules/tgw_asg_master/main.tf b/modules/tgw_asg_master/main.tf
new file mode 100755
index 0000000..48f35f1
--- /dev/null
+++ b/modules/tgw_asg_master/main.tf
@@ -0,0 +1,47 @@
+
+// --- VPC ---
+module "launch_vpc" {
+ source = "../vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = {}
+ subnets_bit_length = var.subnets_bit_length
+}
+
+module "launch_tgw_asg_into_vpc" {
+ source = "../tgw_asg"
+
+ vpc_id = module.launch_vpc.vpc_id
+ gateways_subnets = module.launch_vpc.public_subnets_ids_list
+ key_name = var.key_name
+ enable_volume_encryption = var.enable_volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ allow_upload_download = var.allow_upload_download
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ gateways_min_group_size = var.gateways_min_group_size
+ gateways_max_group_size = var.gateways_max_group_size
+ gateway_version = var.gateway_version
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ gateway_SICKey = var.gateway_SICKey
+ enable_cloudwatch = var.enable_cloudwatch
+ asn = var.asn
+ management_deploy = var.management_deploy
+ management_instance_type = var.management_instance_type
+ management_version = var.management_version
+ management_password_hash = var.management_password_hash
+ management_maintenance_mode_password_hash = var.management_maintenance_mode_password_hash
+ management_permissions = var.management_permissions
+ management_predefined_role = var.management_predefined_role
+ gateways_blades = var.gateways_blades
+ admin_cidr = var.admin_cidr
+ gateways_addresses = var.gateways_addresses
+ gateway_management = var.gateway_management
+ control_gateway_over_public_or_private_address = var.control_gateway_over_public_or_private_address
+ management_server = var.management_server
+ configuration_template = var.configuration_template
+}
diff --git a/modules/tgw_asg_master/output.tf b/modules/tgw_asg_master/output.tf
new file mode 100755
index 0000000..ed183c0
--- /dev/null
+++ b/modules/tgw_asg_master/output.tf
@@ -0,0 +1,24 @@
+output "vpc_id" {
+ value = module.launch_vpc.vpc_id
+}
+output "public_subnets_ids_list" {
+ value = module.launch_vpc.public_subnets_ids_list
+}
+output "management_instance_name" {
+ value = module.launch_tgw_asg_into_vpc.management_instance_name
+}
+output "configuration_template" {
+ value = module.launch_tgw_asg_into_vpc.configuration_template
+}
+output "controller_name" {
+ value = module.launch_tgw_asg_into_vpc.controller_name
+}
+output "management_public_ip" {
+ value = module.launch_tgw_asg_into_vpc.management_public_ip
+}
+output "management_url" {
+ value = module.launch_tgw_asg_into_vpc.management_url
+}
+output "autoscaling_group_name" {
+ value = module.launch_tgw_asg_into_vpc.autoscaling_group_name
+}
diff --git a/modules/tgw_asg_master/variables.tf b/modules/tgw_asg_master/variables.tf
new file mode 100755
index 0000000..b8a6717
--- /dev/null
+++ b/modules/tgw_asg_master/variables.tf
@@ -0,0 +1,199 @@
+// Module: Check Point CloudGuard Network Transit Gateway Auto Scaling Group
+// Deploy an Auto Scaling Group of CloudGuard Security Gateways for Transit Gateway with an optional Management Server in a new VPC
+
+// --- Network Configuration ---
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1} ) "
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+
+// --- General Settings ---
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+
+// --- Check Point CloudGuard Network Security Gateways Auto Scaling Group Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Gateway"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_gateway_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "gateways_min_group_size" {
+ type = number
+ description = "The minimal number of Security Gateways"
+ default = 2
+}
+variable "gateways_max_group_size" {
+ type = number
+ description = "The maximal number of Security Gateways"
+ default = 10
+}
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the gateway instances, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "asn" {
+ type = string
+ description = "The organization Autonomous System Number (ASN) that identifies the routing domain for the Security Gateways"
+ default = "6500"
+}
+
+// --- Check Point CloudGuard Network Security Management Server Configuration ---
+variable "management_deploy" {
+ type = bool
+ description = "Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section"
+ default = true
+}
+variable "management_instance_type" {
+ type = string
+ description = "The EC2 instance type of the Security Management Server"
+ default = "m5.xlarge"
+}
+module "validate_management_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "management"
+ instance_type = var.management_instance_type
+}
+variable "management_version" {
+ type = string
+ description = "The license to install on the Security Management Server"
+ default = "R81.20-BYOL"
+}
+module "validate_management_version" {
+ source = "../version_license"
+
+ chkp_type = "management"
+ version_license = var.management_version
+}
+variable "management_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "management_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the management instance, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+variable "management_permissions" {
+ type = string
+ description = "IAM role to attach to the instance profile"
+ default = "Create with read-write permissions"
+}
+variable "management_predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the instance profile. Ignored if IAM role is not set to 'Use existing'"
+ default = ""
+}
+variable "gateways_blades" {
+ type = bool
+ description = "Turn on the Intrusion Prevention System, Application Control, Anti-Virus and Anti-Bot Blades (additional Blades can be manually turned on later)"
+ default = true
+}
+variable "admin_cidr" {
+ type = string
+ description = "Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server"
+}
+variable "gateways_addresses" {
+ type = string
+ description = "Allow gateways only from this network to communicate with the Security Management Server"
+}
+variable "gateway_management" {
+ type = string
+ description = "Select 'Over the internet' if any of the gateways you wish to manage are not directly accessed via their private IP address"
+ default = "Locally managed"
+}
+
+// --- Automatic Provisioning with Security Management Server Settings ---
+variable "control_gateway_over_public_or_private_address" {
+ type = string
+ description = "Determines if the gateways are provisioned using their private or public address"
+ default = "private"
+}
+variable "management_server" {
+ type = string
+ description = "(Optional) The name that represents the Security Management Server in the automatic provisioning configuration"
+ default = "management-server"
+}
+variable "configuration_template" {
+ type = string
+ description = "(Optional) A name of a Security Gateway configuration template in the automatic provisioning configuration"
+ default = "TGW-ASG-configuration"
+ validation {
+ condition = length(var.configuration_template) < 31
+ error_message = "The configuration_template name can not exceed 30 characters"
+ }
+}
diff --git a/modules/tgw_asg_master/versions.tf b/modules/tgw_asg_master/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/tgw_asg_master/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/tgw_cross_az_cluster/README.md b/modules/tgw_cross_az_cluster/README.md
new file mode 100755
index 0000000..8059b43
--- /dev/null
+++ b/modules/tgw_cross_az_cluster/README.md
@@ -0,0 +1,155 @@
+# Check Point CloudGuard Network Security Cross AZ Cluster for Transit Gateway Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Cross AZ Cluster into an existing VPC on AWS for Transit Gateway.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Deploying a Check Point Cluster in AWS (Amazon Web Services)](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_for_AWS_Cross_AZ_Cluster/Default.htm) for additional information
+
+This solution uses the following modules:
+- amis
+- cluster_iam_role
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/tgw_cross_az_cluster"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-1234"
+ public_subnet_1 = "subnet-1234"
+ public_subnet_2 = "subnet-2345"
+ private_subnet_1 = "subnet-3456"
+ private_subnet_2 = "subnet-4567"
+ tgw_subnet_1_id = "subnet-5678"
+ tgw_subnet_2_id = "subnet-6789"
+ private_route_table = ""
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Cluster-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+ predefined_role = ""
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ memberAToken = ""
+ memberBToken = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+}
+ ```
+
+- Conditional creation
+ - To create an Elastic IP and associate it to each cluster member instance:
+ ```
+ allocate_and_associate_eip = "true"
+ ```
+ - To create IAM Role:
+ ```
+ predefined_role = ""
+ ```
+ - To create route from '0.0.0.0/0' to the Active Cluster member instance, please provide route table:
+ ```
+ private_route_table = "rtb-12345678"
+ ```
+
+ ### Optional re-deploy of cluster member:
+ In case of re-deploying one cluster member, make sure that it's in STANDBY state, and the second member is the ACTIVE one.
+ Follow the commands below in order to re-deploy (replace MEMBER with a or b):
+ - terraform taint aws_instance.member-MEMBER-instance
+ - terraform plan (review the changes)
+ - terraform apply
+ - In Smart Console: reset SIC with the re-deployed member and install policy
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| vpc_id | The VPC id in which to deploy | string | |
+| public_subnet_id | The public subnet of the cluster. The cluster's public IPs will be generated from this subnet | string | |
+| private_subnet_id | The private subnet of the cluster. The cluster's private IPs will be generated from this subnet | string | |
+| tgw_subnet_1_id | The TGW attachment subnet ID located in the 1st Availability Zone | string | |
+| tgw_subnet_2_id | The TGW attachment subnet ID located in the 2nd Availability Zone | string | |
+| private_route_table | (Optional) Set 0.0.0.0/0 route to the Active Cluster member instance in this route table | string | |
+| gateway_name | (Optional) The name tag of the Security Gateway instances | string | **Default:** Check-Point-Cluster-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | |
+| allocate_and_associate_eip | If true, an elastic IP will be allocated and associated with each cluster member | bool | true/false
**Default:** true |
+| volume_size | Root volume size (GB) - minimum 100 | number | **Default:** 100 |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| volume_encryption | KMS or CMK key Identifier. Use key ID, alias, or ARN. | string | **Default:** alias/aws/ebs |
+| enable_instance_connect | Enable AWS Instance Connect | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents an instance from accidental termination | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| instance_tags | (Optional) A map of tags as key=value pairs | map(string) | **Default:** {} |
+| predefined_role | (Optional) A predefined IAM role to attach to the cluster profile | string | |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/tcsh
**Default:** /etc/cli.sh |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components. | string | **Default:** "12345678" |
+| gateway_password_hash | (Optional) Admin user's password hash | string | |
+| memberAToken | (Recommended) Quick connect to Smart-1 Cloud. | string | |
+| memberBToken | (Recommended) Quick connect to Smart-1 Cloud. | string | |
+| resources_tag_name | (Optional) Name tag prefix of the resources | string | |
+| gateway_hostname | (Optional) The host name will be appended with member-a/b accordingly | string | |
+| allow_upload_download | Automatically download Blade Contracts and other important data. | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon-separated commands to run on the initial boot | string | |
+| primary_ntp | (Optional) The IPv4 addresses of Network Time Protocol primary server | string | **Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) The IPv4 addresses of Network Time Protocol secondary server | string | **Default:** 0.pool.ntp.org |
+| gateway_maintenance_mode_password_hash | (Optional) Admin user's maintenance-mode password hash | string | |
+| management_maintenance_mode_password_hash | (Optional) Management's maintenance-mode password hash | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|--------------------|-----------------------------------|
+| cluster_public_ip | The public address of the cluster |
+| member_a_public_ip | The public address of member A |
+| member_b_public_ip | The public address of member B |
+| member_a_ssh | SSH command to member A |
+| member_b_ssh | SSH command to member B |
+| member_a_url | URL to the member A portal |
+| member_b_url | URL to the member B portal |
diff --git a/modules/tgw_cross_az_cluster/locals.tf b/modules/tgw_cross_az_cluster/locals.tf
new file mode 100755
index 0000000..9a9929b
--- /dev/null
+++ b/modules/tgw_cross_az_cluster/locals.tf
@@ -0,0 +1,60 @@
+locals {
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ create_iam_role = var.predefined_role == "" ? 1 : 0
+ provided_roue_table = var.private_route_table == "" ? 0 : 1
+ internal_route_table_condition = var.private_route_table != "" ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ is_both_tokens_used = length(var.memberAToken) > 0 == length(var.memberBToken) > 0
+ validation_message_both = "Smart-1 Cloud Tokens for member A and member B can not be empty."
+ //Will fail if var.memberAToken is empty and var.memberBToken isn't and vice versa
+ regex_s1c_validate = regex("^$", (local.is_both_tokens_used ? "" : local.validation_message_both))
+
+ is_tokens_used = length(var.memberAToken) > 0
+ is_both_tokens_the_same = var.memberAToken == var.memberBToken
+ validation_message_unique = "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
+ //Will fail if both s1c tokens are the same
+ regex_s1c_unique = local.is_tokens_used ? regex("^$", (local.is_both_tokens_the_same ? local.validation_message_unique : "")) : ""
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.gateway_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.gateway_hostname) == var.gateway_hostname ? 0 : "Variable [gateway_hostname] must be a valid hostname label or an empty string"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ gateway_bootstrap_script64 = base64encode(var.gateway_bootstrap_script)
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.gateway_version), 0)
+
+ volume_type_allowed_values = [
+ "gp3",
+ "gp2"]
+ // will fail if [var.VolumeType] is invalid:
+ validate_volume_type = index(local.volume_type_allowed_values, var.volume_type)
+}
diff --git a/modules/tgw_cross_az_cluster/main.tf b/modules/tgw_cross_az_cluster/main.tf
new file mode 100755
index 0000000..f965800
--- /dev/null
+++ b/modules/tgw_cross_az_cluster/main.tf
@@ -0,0 +1,53 @@
+module "cluster_into_vpc" {
+ source = "../cross_az_cluster"
+
+ vpc_id = var.vpc_id
+ public_subnet_ids = tolist([var.public_subnet_1, var.public_subnet_2])
+ private_subnet_ids = tolist([var.private_subnet_1, var.private_subnet_2])
+ security_rules = var.security_rules
+ private_route_table = var.private_route_table
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ volume_size = var.volume_size
+ volume_encryption = var.volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ instance_tags = var.instance_tags
+ predefined_role = var.predefined_role
+ gateway_version = var.gateway_version
+ admin_shell = var.admin_shell
+ gateway_SICKey = var.gateway_SICKey
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ memberAToken = var.memberAToken
+ memberBToken = var.memberBToken
+ resources_tag_name = var.resources_tag_name
+ gateway_hostname = var.gateway_hostname
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = var.gateway_bootstrap_script
+ primary_ntp = var.primary_ntp
+ secondary_ntp = var.secondary_ntp
+ volume_type = var.volume_type
+}
+resource "aws_route_table" "tgw_route_table" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ network_interface_id = module.cluster_into_vpc.member_a_eni
+ }
+ tags = {
+ Name = "TGW Attachment Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "tgw_attachment1_rtb_assoc" {
+ subnet_id = var.tgw_subnet_1_id
+ route_table_id = aws_route_table.tgw_route_table.id
+}
+resource "aws_route_table_association" "tgw_attachment2_rtb_assoc" {
+ subnet_id = var.tgw_subnet_2_id
+ route_table_id = aws_route_table.tgw_route_table.id
+}
\ No newline at end of file
diff --git a/modules/tgw_cross_az_cluster/output.tf b/modules/tgw_cross_az_cluster/output.tf
new file mode 100755
index 0000000..2aa6d33
--- /dev/null
+++ b/modules/tgw_cross_az_cluster/output.tf
@@ -0,0 +1,27 @@
+output "cluster_public_ip" {
+ value = module.cluster_into_vpc.cluster_public_ip
+}
+output "member_a_public_ip" {
+ value = module.cluster_into_vpc.member_a_public_ip
+}
+output "member_b_public_ip" {
+ value = module.cluster_into_vpc.member_b_public_ip
+}
+output "member_a_eni" {
+ value = module.cluster_into_vpc.member_a_eni
+}
+output "member_a_ssh" {
+ value = module.cluster_into_vpc.member_a_ssh
+}
+output "member_b_ssh" {
+ value = module.cluster_into_vpc.member_b_ssh
+}
+output "member_a_url" {
+ value = module.cluster_into_vpc.member_a_url
+}
+output "member_b_url" {
+ value = module.cluster_into_vpc.member_b_url
+}
+output "member_b_eni" {
+ value = module.cluster_into_vpc.member_b_eni
+}
\ No newline at end of file
diff --git a/modules/tgw_cross_az_cluster/variables.tf b/modules/tgw_cross_az_cluster/variables.tf
new file mode 100755
index 0000000..a571796
--- /dev/null
+++ b/modules/tgw_cross_az_cluster/variables.tf
@@ -0,0 +1,195 @@
+// Module: Check Point CloudGuard Network Security Cluster into an existing VPC
+
+// --- VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "public_subnet_1" {
+ type = string
+ description = "The public subnet ID of the cluster that located in the 1st Availability Zone"
+}
+variable "public_subnet_2" {
+ type = string
+ description = "The public subnet of the cluster that located in the 2st Availability Zone"
+}
+variable "private_subnet_1" {
+ type = string
+ description = "The private subnet of the cluster that located in the 1st Availability Zone"
+}
+variable "private_subnet_2" {
+ type = string
+ description = "The private subnet of the cluster that located in the 2st Availability Zone"
+}
+variable "tgw_subnet_1_id" {
+ type = string
+ description = "The TGW attachment subnet ID located in the 1st Availability Zone"
+}
+variable "tgw_subnet_2_id" {
+ type = string
+ description = "The TGW attachment subnet ID located in the 2st Availability Zone"
+}
+variable "private_route_table" {
+ type = string
+ description = "(Optional) Set 0.0.0.0/0 route to the Active Cluster member instance in this route table (e.g. rtb-12a34567). Route table cannot have an existing 0.0.0.0/0 route"
+ default= ""
+}
+
+// --- EC2 Instance Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Cluster-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "allocate_and_associate_eip" {
+ type = bool
+ description = "If set to true, an elastic IP will be allocated and associated with each cluster member, in addition to the shared cluster Elastic IP"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_type" {
+ type = string
+ description = "General Purpose SSD Volume Type"
+ default = "gp3"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instances"
+ default = {}
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the cluster profile"
+ default = ""
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the gateway instances, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+// --- Quick connect to Smart-1 Cloud (Recommended) ---
+variable "memberAToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+variable "memberBToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) Name tag prefix of the resources"
+ default = ""
+}
+variable "gateway_hostname" {
+ type = string
+ description = "(Optional) The host name will be appended with member-a/b accordingly"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/tgw_cross_az_cluster/versions.tf b/modules/tgw_cross_az_cluster/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/tgw_cross_az_cluster/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/tgw_cross_az_cluster_master/README.md b/modules/tgw_cross_az_cluster_master/README.md
new file mode 100755
index 0000000..21f314b
--- /dev/null
+++ b/modules/tgw_cross_az_cluster_master/README.md
@@ -0,0 +1,162 @@
+# Check Point CloudGuard Network Security Cross AZ Cluster for Transit Gateway Terraform module for AWS
+
+Terraform module which deploys a Check Point CloudGuard Network Security Cross AZ Cluster with a new VPC on AWS for Transit Gateway.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
+* [Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html)
+* [Network interface](https://www.terraform.io/docs/providers/aws/r/network_interface.html)
+* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation
+
+See the [Deploying a Check Point Cluster in AWS (Amazon Web Services)](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_for_AWS_Cross_AZ_Cluster/Default.htm) for additional information
+
+This solution uses the following modules:
+- amis
+- cluster_iam_role
+
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+**Instead of the standard terraform apply command, use the following:**
+```
+ terraform apply -target=module.{module_name}.aws_route_table.private_subnet_rtb -auto-approve && terraform apply
+ ```
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/tgw_cross_az_cluster_master"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ "us-east-1b" = 2
+ }
+ private_subnets_map = {
+ "us-east-1a" = 3
+ "us-east-1b" = 4
+ }
+ tgw_subnets_map = {
+ "us-east-1a" = 5
+ "us-east-1b" = 6
+ }
+ subnets_bit_length = 8
+
+ // --- EC2 Instance Configuration ---
+ gateway_name = "Check-Point-Cluster-tf"
+ gateway_instance_type = "c5.xlarge"
+ key_name = "publickey"
+ allocate_and_associate_eip = true
+ volume_size = 100
+ volume_encryption = "alias/aws/ebs"
+ enable_instance_connect = false
+ disable_instance_termination = false
+ instance_tags = {
+ key1 = "value1"
+ key2 = "value2"
+ }
+ predefined_role = ""
+
+ // --- Check Point Settings ---
+ gateway_version = "R81.20-BYOL"
+ admin_shell = "/etc/cli.sh"
+ gateway_SICKey = "12345678"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ // --- Quick connect to Smart-1 Cloud (Recommended) ---
+ memberAToken = ""
+ memberBToken = ""
+
+ // --- Advanced Settings ---
+ resources_tag_name = "tag-name"
+ gateway_hostname = "gw-hostname"
+ allow_upload_download = true
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+ primary_ntp = ""
+ secondary_ntp = ""
+}
+ ```
+
+- Conditional creation
+ - To create an Elastic IP and associate it to each cluster member instance:
+ ```
+ allocate_and_associate_eip = "true"
+ ```
+ - To create IAM Role:
+ ```
+ predefined_role = ""
+ ```
+ - To create route from '0.0.0.0/0' to the Active Cluster member instance, please provide route table:
+ ```
+ private_route_table = "rtb-12345678"
+ ```
+
+ ### Optional re-deploy of cluster member:
+ In case of re-deploying one cluster member, make sure that it's in STANDBY state, and the second member is the ACTIVE one.
+ Follow the commands below in order to re-deploy (replace MEMBER with a or b):
+ - terraform taint aws_instance.member-MEMBER-instance
+ - terraform plan (review the changes)
+ - terraform apply
+ - In Smart Console: reset SIC with the re-deployed member and install policy
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|-------------|------------------------------------------------------------------------------------------------------------------|
+| vpc_cidr | The CIDR block of the VPC | string | |
+| public_subnets_map | A map of pairs `{availability-zone = subnet-suffix-number}`. Minimum 2 pairs (e.g. `{"us-east-1a" = 1, "us-east-1b" = 2}`). | map | |
+| private_subnets_map | A map of pairs `{availability-zone = subnet-suffix-number}`. Minimum 2 pairs (e.g. `{"us-east-1a" = 3, "us-east-1b" = 4}`). | map | |
+| tgw_subnets_map | A map of pairs `{availability-zone = subnet-suffix-number}` for the TGW subnets. Minimum 2 pairs (e.g. `{"us-east-1a" = 1}`). | map | |
+| subnets_bit_length | Number of additional bits to extend the VPC CIDR (e.g., VPC CIDR `/16` and subnets bit length `4` results in subnet address `/20`). | number | |
+| gateway_name | (Optional) The name tag of the Security Gateway instances | string |**Default:** Check-Point-Cluster-tf |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | |
+| allocate_and_associate_eip | If true, an elastic IP will be allocated and associated with each cluster member. | bool | true/false
**Default:** true |
+| volume_size | Root volume size (GB) - minimum 100 | number |**Default:** 100 |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| volume_encryption | KMS or CMK key identifier. Use key ID, alias, or ARN. Key alias should be prefixed with `alias/` (e.g., `alias/aws/ebs`). | string |**Default:** alias/aws/ebs |
+| enable_instance_connect | Enable AWS Instance Connect | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents an instance from accidental termination | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| instance_tags | (Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 instances | map(string) |**Default:** {} |
+| predefined_role | (Optional) A predefined IAM role to attach to the cluster profile | string | |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R82-BYOL
**Default:** R81.20-BYOL |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
**Default:** /etc/cli.sh |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components | string |**Default:** "12345678" |
+| gateway_password_hash | (Optional) Admin user's password hash | string | |
+| memberAToken | (Recommended) Quick connect to Smart-1 Cloud. | string | |
+| memberBToken | (Recommended) Quick connect to Smart-1 Cloud. | string | |
+| resources_tag_name | (Optional) Name tag prefix of the resources | string | |
+| gateway_hostname | (Optional) Host name appended with member-a/b accordingly. The name must not contain reserved words (refer to sk40179). | string | |
+| allow_upload_download | Automatically download Blade Contracts and other important data | bool | true/false
**Default:** true |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon-separated commands to run on the initial boot | string | |
+| primary_ntp | (Optional) The IPv4 addresses of Network Time Protocol primary server | string |**Default:** 169.254.169.123 |
+| secondary_ntp | (Optional) The IPv4 addresses of Network Time Protocol secondary server | string |**Default:** 0.pool.ntp.org |
+| gateway_maintenance_mode_password_hash | (Optional) Admin user's maintenance-mode password hash | string | |
+ security_rules | List of security rules for ingress and egress. | list(object({
direction = string
from_port = any
to_port = any
protocol = any
cidr_blocks = list(any)
})) | **Default:** []|
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+
+| Name | Description |
+|--------------------|-----------------------------------|
+| cluster_public_ip | The public address of the cluster |
+| member_a_public_ip | The public address of member A |
+| member_b_public_ip | The public address of member B |
+| member_a_ssh | SSH command to member A |
+| member_b_ssh | SSH command to member B |
+| member_a_url | URL to the member A portal |
+| member_b_url | URL to the member B portal |
diff --git a/modules/tgw_cross_az_cluster_master/locals.tf b/modules/tgw_cross_az_cluster_master/locals.tf
new file mode 100755
index 0000000..387fb7c
--- /dev/null
+++ b/modules/tgw_cross_az_cluster_master/locals.tf
@@ -0,0 +1,61 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ admin_shell_allowed_values = [
+ "/etc/cli.sh",
+ "/bin/bash",
+ "/bin/csh",
+ "/bin/tcsh"]
+ // Will fail if var.admin_shell is invalid
+ validate_admin_shell = index(local.admin_shell_allowed_values, var.admin_shell)
+
+ create_iam_role = var.predefined_role == "" ? 1 : 0
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ is_both_tokens_used = length(var.memberAToken) > 0 == length(var.memberBToken) > 0
+ validation_message_both = "Smart-1 Cloud Tokens for member A and member B can not be empty."
+ //Will fail if var.memberAToken is empty and var.memberBToken isn't and vice versa
+ regex_s1c_validate = regex("^$", (local.is_both_tokens_used ? "" : local.validation_message_both))
+
+ is_tokens_used = length(var.memberAToken) > 0
+ is_both_tokens_the_same = var.memberAToken == var.memberBToken
+ validation_message_unique = "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
+ //Will fail if both s1c tokens are the same
+ regex_s1c_unique = local.is_tokens_used ? regex("^$", (local.is_both_tokens_the_same ? local.validation_message_unique : "")) : ""
+
+ regex_valid_gateway_hostname = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.gateway_hostname is invalid
+ regex_gateway_hostname = regex(local.regex_valid_gateway_hostname, var.gateway_hostname) == var.gateway_hostname ? 0 : "Variable [gateway_hostname] must be a valid hostname label or an empty string"
+ volume_encryption_condition = var.volume_encryption != "" ? true : false
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_primary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.primary_ntp is invalid
+ regex_primary_ntp = regex(local.regex_valid_primary_ntp, var.primary_ntp) == var.primary_ntp ? 0 : "Variable [primary_ntp] must be a valid ntp"
+
+ regex_valid_secondary_ntp = "^[\\.a-zA-Z0-9\\-]*$"
+ // Will fail if var.secondary_ntp is invalid
+ regex_secondary_ntp = regex(local.regex_valid_secondary_ntp, var.secondary_ntp) == var.secondary_ntp ? 0 : "Variable [secondary_ntp] must be a valid ntp"
+
+ //Splits the version and licence and returns the os version
+ version_split = element(split("-", var.gateway_version), 0)
+
+ volume_type_allowed_values = [
+ "gp3",
+ "gp2"]
+ // will fail if [var.VolumeType] is invalid:
+ validate_volume_type = index(local.volume_type_allowed_values, var.volume_type)
+}
diff --git a/modules/tgw_cross_az_cluster_master/main.tf b/modules/tgw_cross_az_cluster_master/main.tf
new file mode 100755
index 0000000..f901fa3
--- /dev/null
+++ b/modules/tgw_cross_az_cluster_master/main.tf
@@ -0,0 +1,66 @@
+
+module "launch_vpc" {
+ source = "../vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = var.private_subnets_map
+ tgw_subnets_map = var.tgw_subnets_map
+ subnets_bit_length = var.subnets_bit_length
+}
+resource "aws_route_table" "private_subnet_rtb" {
+ depends_on = [module.launch_vpc]
+ vpc_id = module.launch_vpc.vpc_id
+ tags = {
+ Name = "Private Subnets Route Table"
+ }
+}
+resource "aws_route_table_association" "private_rtb_to_private_subnet1" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ route_table_id = aws_route_table.private_subnet_rtb.id
+ subnet_id = module.launch_vpc.private_subnets_ids_list[0]
+}
+resource "aws_route_table_association" "private_rtb_to_private_subnet2" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ route_table_id = aws_route_table.private_subnet_rtb.id
+ subnet_id = module.launch_vpc.private_subnets_ids_list[1]
+}
+module "tgw_cluster_into_vpc" {
+ depends_on = [module.launch_vpc, aws_route_table.private_subnet_rtb]
+ source = "../tgw_cross_az_cluster"
+
+ security_rules = var.security_rules
+ vpc_id = module.launch_vpc.vpc_id
+ public_subnet_1 = module.launch_vpc.public_subnets_ids_list[0]
+ public_subnet_2 = module.launch_vpc.public_subnets_ids_list[1]
+ private_subnet_1 = module.launch_vpc.private_subnets_ids_list[0]
+ private_subnet_2 = module.launch_vpc.private_subnets_ids_list[1]
+ tgw_subnet_1_id = module.launch_vpc.tgw_subnets_ids_list[0]
+ tgw_subnet_2_id =module.launch_vpc.tgw_subnets_ids_list[1]
+ private_route_table = aws_route_table.private_subnet_rtb.id
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ key_name = var.key_name
+ volume_size = var.volume_size
+ volume_encryption = var.volume_encryption
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ instance_tags = var.instance_tags
+ predefined_role = var.predefined_role
+ gateway_version = var.gateway_version
+ admin_shell = var.admin_shell
+ gateway_SICKey = var.gateway_SICKey
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ memberAToken = var.memberAToken
+ memberBToken = var.memberBToken
+ resources_tag_name = var.resources_tag_name
+ gateway_hostname = var.gateway_hostname
+ allow_upload_download = var.allow_upload_download
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = var.gateway_bootstrap_script
+ primary_ntp = var.primary_ntp
+ secondary_ntp = var.secondary_ntp
+ volume_type = var.volume_type
+}
diff --git a/modules/tgw_cross_az_cluster_master/output.tf b/modules/tgw_cross_az_cluster_master/output.tf
new file mode 100755
index 0000000..fd143a6
--- /dev/null
+++ b/modules/tgw_cross_az_cluster_master/output.tf
@@ -0,0 +1,30 @@
+output "cluster_public_ip" {
+ value = module.tgw_cluster_into_vpc.cluster_public_ip
+}
+output "member_a_public_ip" {
+ value = module.tgw_cluster_into_vpc.member_a_public_ip
+}
+output "member_b_public_ip" {
+ value = module.tgw_cluster_into_vpc.member_b_public_ip
+}
+output "member_a_ssh" {
+ value = module.tgw_cluster_into_vpc.member_a_ssh
+}
+output "member_b_ssh" {
+ value = module.tgw_cluster_into_vpc.member_b_ssh
+}
+output "member_a_url" {
+ value = module.tgw_cluster_into_vpc.member_a_url
+}
+output "member_b_url" {
+ value = module.tgw_cluster_into_vpc.member_b_url
+}
+output "member_a_eni" {
+ value = module.tgw_cluster_into_vpc.member_a_eni
+}
+output "member_b_eni" {
+ value = module.tgw_cluster_into_vpc.member_b_eni
+}
+output "vpc_id" {
+ value = module.launch_vpc.vpc_id
+}
diff --git a/modules/tgw_cross_az_cluster_master/variables.tf b/modules/tgw_cross_az_cluster_master/variables.tf
new file mode 100755
index 0000000..f268a00
--- /dev/null
+++ b/modules/tgw_cross_az_cluster_master/variables.tf
@@ -0,0 +1,194 @@
+// Module: Check Point CloudGuard Network Security Cluster into an existing VPC
+
+// ---VPC Network Configuration ---
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1} ) "
+}
+resource "null_resource" "tgw_availability_zones_validation1" {
+ count = length(var.public_subnets_map) == 2 ? 0 : "variable public_subnets_map size must be equal to variable 2"
+}
+variable "private_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 1 pair. (e.g. {\"us-east-1a\" = 2} ) "
+}
+resource "null_resource" "tgw_availability_zones_validation2" {
+ count = length(var.private_subnets_map) == 2 ? 0 : "variable private_subnets_map size must be equal to variable 2"
+}
+variable "tgw_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number} for the tgw subnets. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 3} ) "
+}
+resource "null_resource" "tgw_availability_zones_validation3" {
+ count = length(var.tgw_subnets_map) == 2 ? 0 : "variable tgw_subnets_map size must be equal to variable 2"
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+
+
+// --- EC2 Instance Configuration ---
+variable "gateway_name" {
+ type = string
+ description = "(Optional) The name tag of the Security Gateway instances"
+ default = "Check-Point-Cluster-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The instance type of the Security Gateways"
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instance"
+}
+variable "allocate_and_associate_eip" {
+ type = bool
+ description = "If set to true, an elastic IP will be allocated and associated with each cluster member, in addition to the shared cluster Elastic IP"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Volume Size validation - resource will not be created if the volume size is smaller than 100
+ count = var.volume_size >= 100 ? 0 : "volume_size must be at least 100"
+}
+variable "volume_type" {
+ type = string
+ description = "General Purpose SSD Volume Type"
+ default = "gp3"
+}
+variable "volume_encryption" {
+ type = string
+ description = "KMS or CMK key Identifier: Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs')"
+ default = "alias/aws/ebs"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "instance_tags" {
+ type = map(string)
+ description = "(Optional) A map of tags as key=value pairs. All tags will be added to the Gateway EC2 Instances"
+ default = {}
+}
+variable "predefined_role" {
+ type = string
+ description = "(Optional) A predefined IAM role to attach to the cluster profile"
+ default = ""
+}
+
+// --- Check Point Settings ---
+variable "gateway_version" {
+ type = string
+ description = "Gateway version and license"
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gateway"
+ version_license = var.gateway_version
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters"
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the gateway instances, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+// --- Quick connect to Smart-1 Cloud (Recommended) ---
+variable "memberAToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+variable "memberBToken" {
+ type = string
+ description = "Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud."
+}
+
+// --- Advanced Settings ---
+variable "resources_tag_name" {
+ type = string
+ description = "(Optional) Name tag prefix of the resources"
+ default = ""
+}
+variable "gateway_hostname" {
+ type = string
+ description = "(Optional) The host name will be appended with member-a/b accordingly"
+ default = ""
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics"
+ default = false
+}
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+variable "primary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol primary server"
+ default = "169.254.169.123"
+}
+variable "secondary_ntp" {
+ type = string
+ description = "(Optional) The IPv4 addresses of Network Time Protocol secondary server"
+ default = "0.pool.ntp.org"
+}
+variable "security_rules" {
+ description = "List of security rules for ingress and egress"
+ type = list(object({
+ direction = string # "ingress" or "egress"
+ from_port = number
+ to_port = number
+ protocol = string
+ cidr_blocks = list(string)
+ }))
+ default = []
+}
\ No newline at end of file
diff --git a/modules/tgw_cross_az_cluster_master/versions.tf b/modules/tgw_cross_az_cluster_master/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/tgw_cross_az_cluster_master/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/tgw_gwlb/README.md b/modules/tgw_gwlb/README.md
new file mode 100755
index 0000000..2a61c45
--- /dev/null
+++ b/modules/tgw_gwlb/README.md
@@ -0,0 +1,191 @@
+# Check Point CloudGuard Network Gateway Load Balancer for Transit Gateway Terraform module for AWS
+
+Terraform module which deploys an AWS Auto Scaling group configured for Gateway Load Balancer into existing Centralized Security VPC for Transit Gateway.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
+* [VPC](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc)
+* [Security Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
+* [Load Balancer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb)
+* [Load Balancer Target Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group)
+* [Launch template](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template)
+* [Auto Scaling Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group)
+* [IAM Role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) - conditional creation
+
+See the [Check Point CloudGuard Gateway Load Balancer on AWS](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_Network_for_AWS_Centralized_Gateway_Load_Balancer/Content/Topics-AWS-GWLB-VPC-DG/Introduction.htm) for additional information
+
+This solution uses the following modules:
+- autoscale_gwlb
+- management
+- cme_iam_role_gwlb
+- amis
+- gwlb
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/tgw_gwlb"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration ---
+ vpc_id = "vpc-12345678"
+ internet_gateway_id ="igw-12345"
+ availability_zones = ["us-east-1a", "us-east-1b"]
+ number_of_AZs = 2
+ gateways_subnets= ["subnet-123456", "subnet-234567"]
+
+ transit_gateway_attachment_subnet_1_id="subnet-3456"
+ transit_gateway_attachment_subnet_2_id="subnet-4567"
+ transit_gateway_attachment_subnet_3_id="subnet-5678"
+ transit_gateway_attachment_subnet_4_id="subnet-6789"
+
+ nat_gw_subnet_1_cidr ="10.0.13.0/24"
+ nat_gw_subnet_2_cidr = "10.0.23.0/24"
+ nat_gw_subnet_3_cidr = "10.0.33.0/24"
+ nat_gw_subnet_4_cidr = "10.0.43.0/24"
+
+ gwlbe_subnet_1_cidr = "10.0.14.0/24"
+ gwlbe_subnet_2_cidr = "10.0.24.0/24"
+ gwlbe_subnet_3_cidr = "10.0.34.0/24"
+ gwlbe_subnet_4_cidr = "10.0.44.0/24"
+
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ volume_size = 100
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+ management_server = "CP-Management-gwlb-tf"
+ configuration_template = "gwlb-configuration"
+ admin_shell = "/etc/cli.sh"
+
+ // --- Gateway Load Balancer Configuration ---
+ gateway_load_balancer_name = "gwlb1"
+ target_group_name = "tg1"
+ connection_acceptance_required = "false"
+ enable_cross_zone_load_balancing = "true"
+
+ // --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = "Check-Point-GW-tf"
+ gateway_instance_type = "c5.xlarge"
+ minimum_group_size = 2
+ maximum_group_size = 10
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ gateways_provision_address_type = "private"
+ allocate_public_IP = false
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+
+ // --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ gateways_policy = "Standard"
+ gateway_management = "Locally managed"
+ admin_cidr = ""
+ gateways_addresses = ""
+
+ // --- Other parameters ---
+ VolumeType = "gp3"
+}
+```
+
+- Conditional creation
+ - To enable cloudwatch for tgw_gwlb:
+```
+ enable_cloudwatch = true
+```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To deploy Security Management Server:
+```
+ management_deploy = true
+```
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| vpc_id | Select an existing VPC | string | |
+| internet_gateway_id | VPC's Internet Gateway Id | string | |
+| availability_zones | The Availability Zones (AZs) to use for the subnets in the VPC. | string | |
+| Number_of_AZs | Number of Availability Zones to use in the VPC. | number | **Default:** 2 |
+| Gateways_subnets | Select at least 2 public subnets in the VPC. If you choose to deploy a Security Management Server it will be deployed in the first subnet | string | |
+| transit_gateway_attachment_subnet_1_id | The TGW attachment subnet ID located in the 1st Availability Zone | string | |
+| transit_gateway_attachment_subnet_2_id | The TGW attachment subnet ID located in the 2nd Availability Zone | string | |
+| transit_gateway_attachment_subnet_3_id | The TGW attachment subnet ID located in the 3rd Availability Zone | string | |
+| transit_gateway_attachment_subnet_4_id | The TGW attachment subnet ID located in the 4th Availability Zone | string | |
+| nat_gw_subnet_1_cidr | CIDR block for NAT subnet 1 located in the 1st Availability Zone | string | **Default:** 10.0.13.0/24 |
+| nat_gw_subnet_2_cidr | CIDR block for NAT subnet 2 located in the 2nd Availability Zone | string | **Default:** 10.0.23.0/24 |
+| nat_gw_subnet_3_cidr | CIDR block for NAT subnet 3 located in the 3rd Availability Zone | string | **Default:** 10.0.33.0/24 |
+| nat_gw_subnet_4_cidr | CIDR block for NAT subnet 4 located in the 4th Availability Zone | string | **Default:** 10.0.43.0/24 |
+| gwlbe_subnet_1_cidr | CIDR block for GWLBe subnet 1 located in the 1st Availability Zone | string | **Default:** 10.0.14.0/24 |
+| gwlbe_subnet_2_cidr | CIDR block for GWLBe subnet 2 located in the 2nd Availability Zone | string | **Default:** 10.0.24.0/24 |
+| gwlbe_subnet_3_cidr | CIDR block for GWLBe subnet 3 located in the 3rd Availability Zone | string | **Default:** 10.0.34.0/24 |
+| gwlbe_subnet_4_cidr | CIDR block for GWLBe subnet 4 located in the 4th Availability Zone | string | **Default:** 10.0.44.0/24 |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| management_server | The name that represents the Security Management Server in the automatic provisioning configuration | string | **Default:** CP-Management-gwlb-tf |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents an instance from accidental termination. Note: Once this attribute is true terraform destroy won't work properly | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false
**Default:** true |
+| volume_size | Instances volume size | number | **Default:** 100 |
+| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false
**Default:** true |
+| configuration_template | The tag is used by the Security Management Server to automatically provision the Security Gateways. Must be up to 12 alphanumeric characters and unique for each Quick Start deployment | string | **Default:** gwlb-ter |
+| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh
**Default:** /etc/cli.sh |
+| gateway_load_balancer_name | Load Balancer name in AWS | string | **Default:** gwlb-terraform |
+| target_group_name | Target Group Name. This name must be unique within your AWS account and can have a maximum of 32 alphanumeric characters and hyphens. | string | **Default:** tg1-terraform |
+| connection_acceptance_required | Indicate whether requests from service consumers to create an endpoint to your service must be accepted. Default is set to false (acceptance not required). | bool | true/false
**Default:** false |
+| enable_cross_zone_load_balancing | Select 'true' to enable cross-az load balancing. NOTE! this may cause a spike in cross-az charges. | bool | true/false
**Default:** true |
+| gateway_name | The name tag of the Security Gateway instances. (optional) | string | **Default:** gwlb-terraform |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| gateways_min_group_size | The minimal number of Security Gateways | number | **Default:** 2 |
+| gateways_max_group_size | The maximal number of Security Gateways | number | **Default:** 10 |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R81.20-PAYG-NGTX
- R82-BYOL
- R82-PAYG-NGTP
- R82-PAYG-NGTX
**Default:** R81.20-BYOL |
+| gateway_password_hash | (Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash) | string | |
+| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters | string | **Default:** "12345678" |
+| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) An optional script with semicolon (;) separated commands to run on the initial boot | string | |
+| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address. | string | - private
- public
**Default:** private |
+| allocate_public_IP | Allocate a Public IP for gateway members. | bool | true/false
**Default:** false |
+| management_deploy | Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section | bool | true/false
**Default:** true |
+| management_instance_type | The EC2 instance type of the Security Management Server | string | - c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** m5.xlarge |
+| management_version | The license to install on the Security Management Server | string | - R81.10-BYOL
- R81.10-PAYG
- R81.20-BYOL
- R81.20-PAYG
**Default:** R81.20-BYOL |
+| management_password_hash | (Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash) | string | |
+| gateways_policy | The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group | string | **Default:** Standard |
+| gateway_management | Select 'Over the internet' if any of the gateways you wish to manage are not directly accessed via their private IP address. | string | - Locally managed
- Over the internet
**Default:** Locally managed |
+| admin_cidr | (CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Management Server | string | valid CIDR |
+| gateway_addresses | (CIDR) Allow gateways only from this network to communicate with the Management Server | string | valid CIDR |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| gateway_maintenance_mode_password_hash | Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. | string | |
+| management_maintenance_mode_password_hash | Check Point recommends setting Admin user's password and maintenance-mode password for recovery purposes. | string | |
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|---------------------|---------------------------------------------------------------------------------------|
+| managment_public_ip | The deployed Security Management AWS instance public IP |
+| load_balancer_url | The URL of the external Load Balancer |
+| template_name | Name of a gateway configuration template in the automatic provisioning configuration. |
+| controller_name | The controller name in CME. |
+| gwlb_name | The name of the deployed Gateway Load Balancer |
+| gwlb_service_name | The service name for the deployed Gateway Load Balancer |
+| gwlb_arn | The arn for the deployed Gateway Load Balancer |
diff --git a/modules/tgw_gwlb/locals.tf b/modules/tgw_gwlb/locals.tf
new file mode 100755
index 0000000..0693df6
--- /dev/null
+++ b/modules/tgw_gwlb/locals.tf
@@ -0,0 +1,60 @@
+locals {
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ control_over_public_or_private_allowed_values = [
+ "public",
+ "private"]
+ // will fail if [var.control_gateway_over_public_or_private_address] is invalid:
+ validate_control_over_public_or_private = index(local.control_over_public_or_private_allowed_values, var.gateways_provision_address_type)
+
+ gateway_management_allowed_values = [
+ "Locally managed",
+ "Over the internet"]
+ // will fail if [var.gateway_management] is invalid:
+ validate_gateway_management = index(local.gateway_management_allowed_values, var.gateway_management)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_management_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.management_password_hash is invalid
+ regex_management_password_hash = regex(local.regex_valid_management_password_hash, var.management_password_hash) == var.management_password_hash ? 0 : "Variable [management_password_hash] must be a valid password hash"
+ regex_management_maintenance_mode_password_hash = regex(local.regex_valid_management_password_hash, var.management_maintenance_mode_password_hash) == var.management_maintenance_mode_password_hash ? 0 : "Variable [management_maintenance_mode_password_hash] must be a valid password hash"
+
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+
+ regex_valid_admin_cidr = "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
+ // Will fail if var.admin_cidr is invalid
+ regex_admin_cidr = regex(local.regex_valid_admin_cidr, var.admin_cidr) == var.admin_cidr ? 0 : "Variable [admin_cidr] must be a valid CIDR"
+
+ regex_valid_gateways_addresses = "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
+ // Will fail if var.gateways_addresses is invalid
+ regex_gateways_addresses = regex(local.regex_valid_gateways_addresses, var.gateways_addresses) == var.gateways_addresses ? 0 : "Variable [gateways_addresses] must be a valid gateways addresses"
+
+ regex_valid_management_server = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.management_server is invalid
+ regex_management_server = regex(local.regex_valid_management_server, var.management_server) == var.management_server ? 0 : "Variable [management_server] can not be an empty string"
+
+ regex_valid_configuration_template = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.configuration_template is invalid
+ regex_configuration_template = regex(local.regex_valid_configuration_template, var.configuration_template) == var.configuration_template ? 0 : "Variable [configuration_template] can not be an empty string"
+
+ deploy_management_condition = var.management_deploy == true
+
+ volume_type_allowed_values = [
+ "gp3",
+ "gp2"]
+ // will fail if [var.VolumeType] is invalid:
+ validate_volume_type = index(local.volume_type_allowed_values, var.volume_type)
+
+
+ #note: we need to add validiation for every subnet in masters solution
+}
\ No newline at end of file
diff --git a/modules/tgw_gwlb/main.tf b/modules/tgw_gwlb/main.tf
new file mode 100755
index 0000000..f689c16
--- /dev/null
+++ b/modules/tgw_gwlb/main.tf
@@ -0,0 +1,430 @@
+
+resource "aws_subnet" "gwlbe_subnet1" {
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 0)
+ cidr_block = var.gwlbe_subnet_1_cidr
+ tags = {
+ Name = "GWLBe subnet 1"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "gwlbe_subnet1_rtb" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ nat_gateway_id = aws_nat_gateway.nat_gateway1.id
+ }
+ tags = {
+ Name = "GWLBe Subnet 1 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "gwlbe_subnet1_rtb_assoc" {
+ subnet_id = aws_subnet.gwlbe_subnet1.id
+ route_table_id = aws_route_table.gwlbe_subnet1_rtb.id
+}
+
+
+resource "aws_subnet" "gwlbe_subnet2" {
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 1)
+ cidr_block = var.gwlbe_subnet_2_cidr
+ tags = {
+ Name = "GWLBe subnet 2"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "gwlbe_subnet2_rtb" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ nat_gateway_id = aws_nat_gateway.nat_gateway2.id
+ }
+ tags = {
+ Name = "GWLBe Subnet 2 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "gwlbe_subnet2_rtb_assoc" {
+ subnet_id = aws_subnet.gwlbe_subnet2.id
+ route_table_id = aws_route_table.gwlbe_subnet2_rtb.id
+}
+
+
+resource "aws_subnet" "gwlbe_subnet3" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 2)
+ cidr_block = var.gwlbe_subnet_3_cidr
+ tags = {
+ Name = "GWLBe subnet 3"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "gwlbe_subnet3_rtb" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ nat_gateway_id = aws_nat_gateway.nat_gateway3[0].id
+ }
+ tags = {
+ Name = "GWLBe Subnet 3 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "gwlbe_subnet3_rtb_assoc" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ subnet_id = aws_subnet.gwlbe_subnet3[0].id
+ route_table_id = aws_route_table.gwlbe_subnet3_rtb[0].id
+}
+
+
+resource "aws_subnet" "gwlbe_subnet4" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 3)
+ cidr_block = var.gwlbe_subnet_4_cidr
+ tags = {
+ Name = "GWLBe subnet 4"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "gwlbe_subnet4_rtb" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ nat_gateway_id = aws_nat_gateway.nat_gateway4[0].id
+ }
+ tags = {
+ Name = "GWLBe Subnet 4 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "gwlbe_subnet4_rtb_assoc" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ subnet_id = aws_subnet.gwlbe_subnet4[0].id
+ route_table_id = aws_route_table.gwlbe_subnet4_rtb[0].id
+}
+
+
+
+
+resource "aws_subnet" "nat_gw_subnet1" {
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 0)
+ cidr_block = var.nat_gw_subnet_1_cidr
+ tags = {
+ Name = "NAT subnet 1"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "nat_gw_subnet1_rtb" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ gateway_id = var.internet_gateway_id
+ }
+ tags = {
+ Name = "NAT Subnet 1 Route Table"
+ Network = "Public"
+ }
+}
+resource "aws_route_table_association" "nat_gw_subnet1_rtb_assoc" {
+ subnet_id = aws_subnet.nat_gw_subnet1.id
+ route_table_id = aws_route_table.nat_gw_subnet1_rtb.id
+}
+
+resource "aws_subnet" "nat_gw_subnet2" {
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 1)
+ cidr_block = var.nat_gw_subnet_2_cidr
+ tags = {
+ Name = "NAT subnet 2"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "nat_gw_subnet2_rtb" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ gateway_id = var.internet_gateway_id
+ }
+ tags = {
+ Name = "NAT Subnet 2 Route Table"
+ Network = "Public"
+ }
+}
+resource "aws_route_table_association" "nat_gw_subnet2_rtb_assoc" {
+ subnet_id = aws_subnet.nat_gw_subnet2.id
+ route_table_id = aws_route_table.nat_gw_subnet2_rtb.id
+}
+
+resource "aws_subnet" "nat_gw_subnet3" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 2)
+ cidr_block = var.nat_gw_subnet_3_cidr
+ tags = {
+ Name = "NAT subnet 3"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "nat_gw_subnet3_rtb" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ gateway_id = var.internet_gateway_id
+ }
+ tags = {
+ Name = "NAT Subnet 3 Route Table"
+ Network = "Public"
+ }
+}
+resource "aws_route_table_association" "nat_gw_subnet3_rtb_assoc" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ subnet_id = aws_subnet.nat_gw_subnet3[0].id
+ route_table_id = aws_route_table.nat_gw_subnet3_rtb[0].id
+}
+
+resource "aws_subnet" "nat_gw_subnet4" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ vpc_id = var.vpc_id
+ availability_zone = element(var.availability_zones, 3)
+ cidr_block = var.nat_gw_subnet_4_cidr
+ tags = {
+ Name = "NAT subnet 4"
+ Network = "Private"
+ }
+}
+resource "aws_route_table" "nat_gw_subnet4_rtb" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ gateway_id = var.internet_gateway_id
+ }
+ tags = {
+ Name = "NAT Subnet 4 Route Table"
+ Network = "Public"
+ }
+}
+resource "aws_route_table_association" "nat_gw_subnet4_rtb_assoc" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ subnet_id = aws_subnet.nat_gw_subnet4[0].id
+ route_table_id = aws_route_table.nat_gw_subnet4_rtb[0].id
+}
+
+module "gwlb" {
+ source = "../gwlb"
+
+ vpc_id = var.vpc_id
+ subnet_ids = var.gateways_subnets
+
+ // --- General Settings ---
+ key_name = var.key_name
+ enable_volume_encryption = var.enable_volume_encryption
+ volume_size = var.volume_size
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ allow_upload_download = var.allow_upload_download
+ management_server = var.management_server
+ configuration_template = var.configuration_template
+ admin_shell = var.admin_shell
+
+ // --- Gateway Load Balancer Configuration ---
+ gateway_load_balancer_name = var.gateway_load_balancer_name
+ target_group_name = var.target_group_name
+ connection_acceptance_required = false
+ enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
+
+ // --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ minimum_group_size = var.minimum_group_size
+ maximum_group_size = var.maximum_group_size
+ gateway_version = var.gateway_version
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ gateway_SICKey = var.gateway_SICKey
+ gateways_provision_address_type = var.gateways_provision_address_type
+ allocate_public_IP = var.allocate_public_IP
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = var.gateway_bootstrap_script
+
+ // --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+ management_deploy = var.management_deploy
+ management_instance_type = var.management_instance_type
+ management_version = var.management_version
+ management_password_hash = var.management_password_hash
+ management_maintenance_mode_password_hash = var.management_maintenance_mode_password_hash
+ gateways_policy = var.gateways_policy
+ gateway_management = var.gateway_management
+ admin_cidr = var.admin_cidr
+ gateways_addresses = var.gateways_addresses
+
+ volume_type = var.volume_type
+}
+
+resource "aws_vpc_endpoint" "gwlb_endpoint1" {
+ depends_on = [module.gwlb, aws_subnet.gwlbe_subnet1]
+ vpc_id = var.vpc_id
+ vpc_endpoint_type = "GatewayLoadBalancer"
+ service_name = module.gwlb.gwlb_service_name
+ subnet_ids = aws_subnet.gwlbe_subnet1[*].id
+ tags = {
+ "Name" = "gwlb_endpoint1"
+ }
+}
+resource "aws_vpc_endpoint" "gwlb_endpoint2" {
+ depends_on = [module.gwlb, aws_subnet.gwlbe_subnet2]
+ vpc_id = var.vpc_id
+ vpc_endpoint_type = "GatewayLoadBalancer"
+ service_name = module.gwlb.gwlb_service_name
+ subnet_ids = aws_subnet.gwlbe_subnet2[*].id
+ tags = {
+ "Name" = "gwlb_endpoint2"
+ }
+}
+resource "aws_vpc_endpoint" "gwlb_endpoint3" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ depends_on = [module.gwlb, aws_subnet.gwlbe_subnet3]
+ vpc_id = var.vpc_id
+ vpc_endpoint_type = "GatewayLoadBalancer"
+ service_name = module.gwlb.gwlb_service_name
+ subnet_ids = aws_subnet.gwlbe_subnet3[*].id
+ tags = {
+ "Name" = "gwlb_endpoint3"
+ }
+}
+resource "aws_vpc_endpoint" "gwlb_endpoint4" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ depends_on = [module.gwlb, aws_subnet.gwlbe_subnet4]
+ vpc_id = var.vpc_id
+ vpc_endpoint_type = "GatewayLoadBalancer"
+ service_name = module.gwlb.gwlb_service_name
+ subnet_ids = aws_subnet.gwlbe_subnet4[*].id
+ tags = {
+ "Name" = "gwlb_endpoint4"
+ }
+}
+
+
+resource "aws_route_table" "tgw_attachment_subnet1_rtb" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ vpc_endpoint_id = aws_vpc_endpoint.gwlb_endpoint1.id
+ }
+ tags = {
+ Name = "TGW Attachment Subnet 1 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "tgw_attachment1_rtb_assoc" {
+ subnet_id = var.transit_gateway_attachment_subnet_1_id
+ route_table_id = aws_route_table.tgw_attachment_subnet1_rtb.id
+}
+resource "aws_route_table" "tgw_attachment_subnet2_rtb" {
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ vpc_endpoint_id = aws_vpc_endpoint.gwlb_endpoint2.id
+ }
+ tags = {
+ Name = "TGW Attachment Subnet 2 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "tgw_attachment2_rtb_assoc" {
+ subnet_id = var.transit_gateway_attachment_subnet_2_id
+ route_table_id = aws_route_table.tgw_attachment_subnet2_rtb.id
+}
+resource "aws_route_table" "tgw_attachment_subnet3_rtb" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ vpc_endpoint_id = aws_vpc_endpoint.gwlb_endpoint3[0].id
+ }
+ tags = {
+ Name = "TGW Attachment Subnet 3 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "tgw_attachment3_rtb_assoc" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ subnet_id = var.transit_gateway_attachment_subnet_3_id
+ route_table_id = aws_route_table.tgw_attachment_subnet3_rtb[0].id
+}
+resource "aws_route_table" "tgw_attachment_subnet4_rtb" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ vpc_id = var.vpc_id
+ route{
+ cidr_block = "0.0.0.0/0"
+ vpc_endpoint_id = aws_vpc_endpoint.gwlb_endpoint4[0].id
+ }
+ tags = {
+ Name = "TGW Attachment Subnet 4 Route Table"
+ Network = "Private"
+ }
+}
+resource "aws_route_table_association" "tgw_attachment4_rtb_assoc" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ subnet_id = var.transit_gateway_attachment_subnet_4_id
+ route_table_id = aws_route_table.tgw_attachment_subnet4_rtb[0].id
+}
+
+
+resource "aws_eip" "nat_gw_public_address1" {
+}
+resource "aws_eip" "nat_gw_public_address2" {
+}
+resource "aws_eip" "nat_gw_public_address3" {
+ count = var.number_of_AZs >= 3 ? 1 : 0
+}
+resource "aws_eip" "nat_gw_public_address4" {
+ count = var.number_of_AZs >= 4 ? 1 : 0
+}
+
+resource "aws_nat_gateway" "nat_gateway1" {
+ depends_on = [aws_subnet.nat_gw_subnet1, aws_eip.nat_gw_public_address1]
+ allocation_id = aws_eip.nat_gw_public_address1.id
+ subnet_id = aws_subnet.nat_gw_subnet1.id
+
+ tags = {
+ Name = "NatGW1"
+ }
+}
+resource "aws_nat_gateway" "nat_gateway2" {
+ depends_on = [aws_subnet.nat_gw_subnet2, aws_eip.nat_gw_public_address2]
+ allocation_id = aws_eip.nat_gw_public_address2.id
+ subnet_id = aws_subnet.nat_gw_subnet2.id
+
+ tags = {
+ Name = "NatGW2"
+ }
+}
+resource "aws_nat_gateway" "nat_gateway3" {
+ count = var.number_of_AZs >= 3 ? 1 :0
+ depends_on = [aws_subnet.nat_gw_subnet3, aws_eip.nat_gw_public_address3]
+ allocation_id = aws_eip.nat_gw_public_address3[0].id
+ subnet_id = aws_subnet.nat_gw_subnet3[0].id
+
+ tags = {
+ Name = "NatGW3"
+ }
+}
+resource "aws_nat_gateway" "nat_gateway4" {
+ count = var.number_of_AZs >= 4 ? 1 :0
+ depends_on = [aws_subnet.nat_gw_subnet4, aws_eip.nat_gw_public_address4]
+ allocation_id = aws_eip.nat_gw_public_address4[0].id
+ subnet_id = aws_subnet.nat_gw_subnet4[0].id
+
+ tags = {
+ Name = "NatGW4"
+ }
+}
\ No newline at end of file
diff --git a/modules/tgw_gwlb/output.tf b/modules/tgw_gwlb/output.tf
new file mode 100755
index 0000000..15cb48a
--- /dev/null
+++ b/modules/tgw_gwlb/output.tf
@@ -0,0 +1,24 @@
+output "Deployment" {
+ value = "Finalizing instances configuration may take up to 20 minutes after deployment is finished."
+}
+output "management_public_ip" {
+ depends_on = [module.gwlb]
+ value = module.gwlb[*].management_public_ip
+}
+output "gwlb_arn" {
+ depends_on = [module.gwlb]
+ value = module.gwlb[*].gwlb_arn
+}
+output "gwlb_service_name" {
+ depends_on = [module.gwlb]
+ value = module.gwlb[*].gwlb_service_name
+}
+output "gwlb_name" {
+ value = var.gateway_load_balancer_name
+}
+output "controller_name" {
+ value = "gwlb-controller"
+}
+output "template_name" {
+ value = var.configuration_template
+}
\ No newline at end of file
diff --git a/modules/tgw_gwlb/variables.tf b/modules/tgw_gwlb/variables.tf
new file mode 100755
index 0000000..a711f33
--- /dev/null
+++ b/modules/tgw_gwlb/variables.tf
@@ -0,0 +1,317 @@
+// Module: Check Point CloudGuard Network Gateway Load Balancer into an existing VPC
+
+// ---VPC Network Configuration ---
+variable "vpc_id" {
+ type = string
+}
+variable "internet_gateway_id" {
+ type = string
+ description = "VPC's Internet Gateway Id (e.g. igw-123a4567)"
+}
+variable "availability_zones"{
+ type = list(string)
+ description = "The Availability Zones (AZs) to use for the subnets in the VPC. Select two (the logical order is preserved)"
+}
+variable "number_of_AZs" {
+ type = number
+ description = "Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter"
+ default = 2
+}
+resource "null_resource" "availability_zones_validation1" {
+ count = var.number_of_AZs == length(var.availability_zones) ? 0 : "variable availability_zones list size must be equal to variable num_of_AZs"
+}
+
+variable "gateways_subnets" {
+ type = list(string)
+ description = "Select at least 2 public subnets in the VPC. If you choose to deploy a Security Management Server it will be deployed in the first subnet"
+}
+
+variable "transit_gateway_attachment_subnet_1_id" {
+ type = string
+ description = "The TGW attachment subnet ID located in the 1st Availability Zone"
+}
+variable "transit_gateway_attachment_subnet_2_id" {
+ type = string
+ description = "The TGW attachment subnet ID located in the 2st Availability Zone"
+}
+variable "transit_gateway_attachment_subnet_3_id" {
+ type = string
+ description = "The TGW attachment subnet ID located in the 3st Availability Zone"
+ default = ""
+}
+variable "transit_gateway_attachment_subnet_4_id" {
+ type = string
+ description = "The TGW attachment subnet ID located in the 4st Availability Zone"
+ default = ""
+}
+variable "nat_gw_subnet_1_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 1 located in the 1st Availability Zone"
+ default = "10.0.13.0/24"
+}
+variable "nat_gw_subnet_2_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 2 located in the 2st Availability Zone"
+ default = "10.0.23.0/24"
+}
+variable "nat_gw_subnet_3_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 3 located in the 3st Availability Zone"
+ default = "10.0.33.0/24"
+}
+variable "nat_gw_subnet_4_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 4 located in the 4st Availability Zone"
+ default = "10.0.43.0/24"
+}
+variable "gwlbe_subnet_1_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 1 located in the 1st Availability Zone"
+ default = "10.0.14.0/24"
+}
+variable "gwlbe_subnet_2_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 2 located in the 2st Availability Zone"
+ default = "10.0.24.0/24"
+}
+variable "gwlbe_subnet_3_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 3 located in the 3st Availability Zone"
+ default = "10.0.34.0/24"
+}
+variable "gwlbe_subnet_4_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 4 located in the 4st Availability Zone"
+ default = "10.0.44.0/24"
+}
+// --- General Settings ---
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Will fail if var.volume_size is less than 100
+ count = var.volume_size >= 100 ? 0 : "variable volume_size must be at least 100"
+}
+variable "volume_type" {
+ type = string
+ description = "General Purpose SSD Volume Type"
+ default = "gp3"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "management_server" {
+ type = string
+ description = "The name that represents the Security Management Server in the automatic provisioning configuration."
+ default = "gwlb-management-server"
+}
+variable "configuration_template" {
+ type = string
+ description = "A name of a gateway configuration template in the automatic provisioning configuration."
+ default = "gwlb-ASG-configuration"
+ validation {
+ condition = length(var.configuration_template) < 31
+ error_message = "The configuration_template name can not exceed 30 characters"
+ }
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+
+// --- Gateway Load Balancer Configuration ---
+
+variable "gateway_load_balancer_name" {
+ type = string
+ description = "Gateway Load Balancer name. This name must be unique within your AWS account and can have a maximum of 32 alphanumeric characters and hyphens. A name cannot begin or end with a hyphen."
+ default = "gwlb1"
+}
+resource "null_resource" "gateway_load_balancer_name_too_long" {
+ // Will fail if gateway_load_balancer_name more than 32
+ count = length(var.gateway_load_balancer_name) <= 32 ? 0 : "variable gateway_load_balancer_name must be at most 32"
+}
+variable "target_group_name" {
+ type = string
+ description = "Target Group Name. This name must be unique within your AWS account and can have a maximum of 32 alphanumeric characters and hyphens. A name cannot begin or end with a hyphen."
+ default = "tg1"
+}
+resource "null_resource" "target_group_name_too_long" {
+ // Will fail if target_group_name more than 32
+ count = length(var.target_group_name) <= 32 ? 0 : "variable target_group_name must be at most 32"
+}
+variable "enable_cross_zone_load_balancing" {
+ type = bool
+ description = "Select 'true' to enable cross-az load balancing. NOTE! this may cause a spike in cross-az charges."
+ default = true
+}
+
+// --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+
+variable "gateway_name" {
+ type = string
+ description = "The name tag of the Security Gateway instances. (optional)"
+ default = "Check-Point-Gateway-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The EC2 instance type for the Security Gateways."
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "minimum_group_size" {
+ type = number
+ description = "The minimal number of Security Gateways."
+ default = 2
+}
+variable "maximum_group_size" {
+ type = number
+ description = "The maximal number of Security Gateways."
+ default = 10
+}
+variable "gateway_version" {
+ type = string
+ description = "The version and license to install on the Security Gateways."
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gwlb_gw"
+ version_license = var.gateway_version
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the gateway instances, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters)"
+}
+
+variable "gateways_provision_address_type" {
+ type = string
+ description = "Determines if the gateways are provisioned using their private or public address"
+ default = "private"
+}
+
+variable "allocate_public_IP" {
+ type = bool
+ description = "Allocate an Elastic IP for security gateway."
+ default = false
+}
+
+resource "null_resource" "invalid_allocation" {
+ // Will fail if var.gateways_provision_address_type is public and var.allocate_public_IP is false
+ count = var.gateways_provision_address_type != "public" ? 0 : var.allocate_public_IP == true ? 0 : "Gateway's selected to be provisioned by public IP, but [allocate_public_IP] parameter is false"
+}
+
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics."
+ default = false
+}
+
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+
+// --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+
+variable "management_deploy" {
+ type = bool
+ description = "Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section"
+ default = true
+}
+variable "management_instance_type" {
+ type = string
+ description = "The EC2 instance type of the Security Management Server"
+ default = "m5.xlarge"
+}
+module "validate_management_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "management"
+ instance_type = var.management_instance_type
+}
+variable "management_version" {
+ type = string
+ description = "The license to install on the Security Management Server"
+ default = "R81.20-BYOL"
+}
+module "validate_management_version" {
+ source = "../version_license"
+
+ chkp_type = "management"
+ version_license = var.management_version
+}
+variable "management_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "management_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the management instance, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+variable "gateways_policy" {
+ type = string
+ description = "The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group"
+ default = "Standard"
+}
+variable "gateway_management" {
+ type = string
+ description = "Select 'Over the internet' if any of the gateways you wish to manage are not directly accessed via their private IP address."
+ default = "Locally managed"
+}
+variable "admin_cidr" {
+ type = string
+ description = "Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server"
+}
+variable "gateways_addresses" {
+ type = string
+ description = "Allow gateways only from this network to communicate with the Security Management Server"
+}
+
diff --git a/modules/tgw_gwlb/versions.tf b/modules/tgw_gwlb/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/tgw_gwlb/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/tgw_gwlb_master/README.md b/modules/tgw_gwlb_master/README.md
new file mode 100755
index 0000000..16090be
--- /dev/null
+++ b/modules/tgw_gwlb_master/README.md
@@ -0,0 +1,194 @@
+# Check Point CloudGuard Network Gateway Load Balancer for Transit Gateway Terraform Master module for AWS
+
+Terraform module which deploys an AWS Auto Scaling group configured for Gateway Load Balancer into new Centralized Security VPC for Transit Gateway.
+
+These types of Terraform resources are supported:
+* [AWS Instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
+* [Security Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
+* [Load Balancer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb)
+* [Load Balancer Target Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group)
+* [Launch template](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template)
+* [Auto Scaling Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group)
+* [IAM Role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) - conditional creation
+
+See the [Check Point CloudGuard Gateway Load Balancer on AWS](https://sc1.checkpoint.com/documents/IaaS/WebAdminGuides/EN/CP_CloudGuard_Network_for_AWS_Centralized_Gateway_Load_Balancer/Content/Topics-AWS-GWLB-VPC-DG/Introduction.htm) for additional information
+
+This solution uses the following modules:
+- autoscale_gwlb
+- vpc
+- management
+- cme_iam_role_gwlb
+- amis
+- gwlb
+
+## Usage
+Follow best practices for using CGNS modules on [the root page](https://registry.terraform.io/modules/checkpointsw/cloudguard-network-security/aws/latest#:~:text=Best%20Practices%20for%20Using%20Our%20Modules).
+
+
+**Example:**
+```
+provider "aws" {}
+
+module "example_module" {
+
+ source = "CheckPointSW/cloudguard-network-security/aws//modules/tgw_gwlb"
+ version = "1.0.2"
+
+ // --- VPC Network Configuration --
+ vpc_cidr = "10.0.0.0/16"
+ public_subnets_map = {
+ "us-east-1a" = 1
+ "us-east-1b" = 2
+ "us-east-1c" = 3
+ "us-east-1d" = 4
+ }
+ tgw_subnets_map = {
+ "us-east-1a" = 5
+ "us-east-1b" = 6
+ "us-east-1c" = 7
+ "us-east-1d" = 8
+ }
+ subnets_bit_length = 8
+
+ availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d"]
+ number_of_AZs = 4
+
+ nat_gw_subnet_1_cidr ="10.0.13.0/24"
+ nat_gw_subnet_2_cidr = "10.0.23.0/24"
+ nat_gw_subnet_3_cidr = "10.0.33.0/24"
+ nat_gw_subnet_4_cidr = "10.0.43.0/24"
+
+ gwlbe_subnet_1_cidr = "10.0.14.0/24"
+ gwlbe_subnet_2_cidr = "10.0.24.0/24"
+ gwlbe_subnet_3_cidr = "10.0.34.0/24"
+ gwlbe_subnet_4_cidr = "10.0.44.0/24"
+
+ // --- General Settings ---
+ key_name = "publickey"
+ enable_volume_encryption = true
+ volume_size = 100
+ enable_instance_connect = false
+ disable_instance_termination = false
+ allow_upload_download = true
+ management_server = "CP-Management-gwlb-tf"
+ configuration_template = "gwlb-configuration"
+ admin_shell = "/etc/cli.sh"
+
+ // --- Gateway Load Balancer Configuration ---
+ gateway_load_balancer_name = "gwlb1"
+ target_group_name = "tg1"
+ enable_cross_zone_load_balancing = "true"
+
+ // --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = "Check-Point-GW-tf"
+ gateway_instance_type = "c5.xlarge"
+ minimum_group_size = 2
+ maximum_group_size = 10
+ gateway_version = "R81.20-BYOL"
+ gateway_password_hash = ""
+ gateway_maintenance_mode_password_hash = "" # For R81.10 and below the gateway_password_hash is used also as maintenance-mode password.
+ gateway_SICKey = "12345678"
+ gateways_provision_address_type = "private"
+ allocate_public_IP = false
+ enable_cloudwatch = false
+ gateway_bootstrap_script = "echo 'this is bootstrap script' > /home/admin/bootstrap.txt"
+
+ // --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+ management_deploy = true
+ management_instance_type = "m5.xlarge"
+ management_version = "R81.20-BYOL"
+ management_password_hash = ""
+ management_maintenance_mode_password_hash = "" # For R81.10 and below the management_password_hash is used also as maintenance-mode password.
+ gateways_policy = "Standard"
+ gateway_management = "Locally managed"
+ admin_cidr = "0.0.0.0/0"
+ gateways_addresses = "0.0.0.0/0"
+
+ // --- Other parameters ---
+ volume_type = "gp3"
+```
+
+- Conditional creation
+ - To enable cloudwatch for tgw_gwlb_master:
+```
+ enable_cloudwatch = true
+```
+ Note: enabling cloudwatch will automatically create IAM role with cloudwatch:PutMetricData permission
+ - To deploy Security Management Server:
+```
+ management_deploy = true
+```
+
+
+## Inputs
+
+| Name | Description | Type | Allowed Values |
+|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| vpc_cidr | The CIDR block of the VPC | string | |
+| subnets_bit_length | Number of additional bits to extend the VPC CIDR. For example, a /16 CIDR with a subnets_bit_length of 4 results in /20 subnets. | number | |
+| public_subnets_map | A map of {availability-zone = subnet-suffix-number}. Minimum 1 pair (e.g., {"us-east-1a" = 1}). | map | |
+| availability_zones | The Availability Zones (AZs) to use for the subnets in the VPC. | string | |
+| Number_of_AZs | Number of Availability Zones to use in the VPC. | number | **Default:** 2 |
+| tgw_subnets_map | A map of {availability-zone = subnet-suffix-number} for TGW subnets. Minimum 2 pairs (e.g., {"us-east-1a" = 1}). | map | |
+| nat_gw_subnet_1_cidr | CIDR block for NAT subnet 1 in the 1st Availability Zone | string | **Default:** 10.0.13.0/24 |
+| nat_gw_subnet_2_cidr | CIDR block for NAT subnet 2 in the 2nd Availability Zone | string | **Default:** 10.0.23.0/24 |
+| nat_gw_subnet_3_cidr | CIDR block for NAT subnet 3 in the 3rd Availability Zone | string | **Default:** 10.0.33.0/24 |
+| nat_gw_subnet_4_cidr | CIDR block for NAT subnet 4 in the 4th Availability Zone | string | **Default:** 10.0.43.0/24 |
+| gwlbe_subnet_1_cidr | CIDR block for GWLBe subnet 1 in the 1st Availability Zone | string | **Default:** 10.0.14.0/24 |
+| gwlbe_subnet_2_cidr | CIDR block for GWLBe subnet 2 in the 2nd Availability Zone | string | **Default:** 10.0.24.0/24 |
+| gwlbe_subnet_3_cidr | CIDR block for GWLBe subnet 3 in the 3rd Availability Zone | string | **Default:** 10.0.34.0/24 |
+| gwlbe_subnet_4_cidr | CIDR block for GWLBe subnet 4 in the 4th Availability Zone | string | **Default:** 10.0.44.0/24 |
+| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | |
+| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false
**Default:** true |
+| enable_instance_connect | Enable SSH connection over AWS web console. Supporting regions can be found [here](https://aws.amazon.com/about-aws/whats-new/2019/06/introducing-amazon-ec2-instance-connect/) | bool | true/false
**Default:** false |
+| disable_instance_termination | Prevents accidental termination. Note: When true, `terraform destroy` won’t work properly. | bool | true/false
**Default:** false |
+| metadata_imdsv2_required | Set true to deploy instances with IMDSv2 metadata token required. | bool | true/false
**Default:** true |
+| volume_size | Instance volume size | number | **Default:** 100 |
+| allow_upload_download | Automatically download Blade Contracts and other data. | bool | true/false
**Default:** true |
+| management_server | The name representing the Security Management Server in the automatic provisioning configuration. | string | **Default:** CP-Management-gwlb-tf |
+| configuration_template | The provisioning tag for the Security Gateways. Must be up to 12 alphanumeric characters and unique. | string | **Default:** gwlb-ter |
+| admin_shell | Set the admin shell for advanced command line configuration. | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh
**Default:** /etc/cli.sh |
+| gateway_load_balancer_name | Load Balancer name in AWS | string | **Default:** gwlb-terraform |
+| target_group_name | Target Group Name. Must be unique within your AWS account with up to 32 alphanumeric characters and hyphens. | string | **Default:** tg1-terraform |
+| connection_acceptance_required | Indicate whether service consumers must accept endpoint requests. Default is false (not required). | bool | true/false
**Default:** false |
+| enable_cross_zone_load_balancing | Enable cross-AZ load balancing. This may increase cross-AZ charges. | bool | true/false
**Default:** true |
+| gateway_name | The name tag of the Security Gateway instances. | string | **Default:** gwlb-terraform |
+| gateway_instance_type | The instance type of the Security Gateways | string | - c4.large
- c4.xlarge
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| gateways_min_group_size | The minimum number of Security Gateways | number | **Default:** 2 |
+| gateways_max_group_size | The maximum number of Security Gateways | number | **Default:** 10 |
+| gateway_version | Gateway version and license | string | - R81.20-BYOL
- R81.20-PAYG-NGTP
- R81.20-PAYG-NGTX
- R82-BYOL
- R82-PAYG-NGTP
- R82-PAYG-NGTX
**Default:** R81.20-BYOL |
+| gateway_password_hash | (Optional) Admin user's password hash (use command `openssl passwd -6 PASSWORD` to get the PASSWORD's hash). | string | |
+| gateway_SICKey | The Secure Internal Communication key for trusted connections between Check Point components. At least 8 alphanumeric characters. | string | **Default:** "12345678" |
+| enable_cloudwatch | Report Check Point-specific CloudWatch metrics. | bool | true/false
**Default:** false |
+| gateway_bootstrap_script | (Optional) Semicolon-separated commands to run on initial boot. | string | |
+| gateways_provision_address_type | Determines if gateways are provisioned using private or public addresses. | string | - private
- public
**Default:** private |
+| allocate_public_IP | Allocate a Public IP for gateway members. | bool | true/false
**Default:** false |
+| management_deploy | Use an existing Security Management Server or deploy a new one. | bool | true/false
**Default:** true |
+| management_instance_type | The EC2 instance type of the Security Management Server | string | - c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- m5.large
- m5.xlarge
- m5.2xlarge
- m5.4xlarge
- m5.8xlarge
- m5.12xlarge
- m5.16xlarge
- m5.24xlarge
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- r5.large
- r5.xlarge
- r5.2xlarge
- r5.4xlarge
- r5.8xlarge
- r5.12xlarge
- r5.16xlarge
- r5.24xlarge
- r5a.large
- r5a.xlarge
- r5a.2xlarge
- r5a.4xlarge
- r5a.8xlarge
- r5a.12xlarge
- r5a.16xlarge
- r5a.24xlarge
- r5b.large
- r5b.xlarge
- r5b.2xlarge
- r5b.4xlarge
- r5b.8xlarge
- r5b.12xlarge
- r5b.16xlarge
- r5b.24xlarge
- r5n.large
- r5n.xlarge
- r5n.2xlarge
- r5n.4xlarge
- r5n.8xlarge
- r5n.12xlarge
- r5n.16xlarge
- r5n.24xlarge
- r6i.large
- r6i.xlarge
- r6i.2xlarge
- r6i.4xlarge
- r6i.8xlarge
- r6i.12xlarge
- r6i.16xlarge
- r6i.24xlarge
- r6i.32xlarge
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
**Default:** c5.xlarge |
+| management_version | The license to install on the Security Management Server. | string | - R81.10-BYOL
- R81.10-PAYG
- R81.20-BYOL
- R81.20-PAYG
**Default:** R81.20-BYOL |
+| management_password_hash | (Optional) Admin user's password hash (use command `openssl passwd -6 PASSWORD` to get the PASSWORD's hash). | string | |
+| gateways_policy | The name of the Security Policy package to install on gateways in the Auto Scaling group. | string | **Default:** Standard |
+| gateway_management | Select 'Over the internet' if managing gateways not directly accessible via private IP addresses. | string | - Locally managed
- Over the internet
**Default:** Locally managed |
+| admin_cidr | (CIDR) Allow web, ssh, and graphical clients from this network to communicate with the Management Server. | string | valid CIDR |
+| gateway_addresses | (CIDR) Allow gateways from this network to communicate with the Management Server. | string | valid CIDR |
+| volume_type | General Purpose SSD Volume Type | string | - gp3
- gp2
**Default:** gp3 |
+| gateway_maintenance_mode_password_hash | (Optional) Maintenance-mode password hash for recovery purposes. | string | |
+| management_maintenance_mode_password_hash | (Optional) Maintenance-mode password hash for recovery purposes. | string | |
+
+
+## Outputs
+To display the outputs defined by the module, create an `outputs.tf` file with the following structure:
+```
+output "instance_public_ip" {
+ value = module.{module_name}.instance_public_ip
+}
+```
+| Name | Description |
+|---------------------|---------------------------------------------------------------------------------------|
+| managment_public_ip | The deployed Security Management AWS instance public IP |
+| load_balancer_url | The URL of the external Load Balancer |
+| template_name | Name of a gateway configuration template in the automatic provisioning configuration. |
+| controller_name | The controller name in CME. |
+| gwlb_name | The name of the deployed Gateway Load Balancer |
+| gwlb_service_name | The service name for the deployed Gateway Load Balancer |
+| gwlb_arn | The arn for the deployed Gateway Load Balancer |
diff --git a/modules/tgw_gwlb_master/locals.tf b/modules/tgw_gwlb_master/locals.tf
new file mode 100755
index 0000000..d75eeaa
--- /dev/null
+++ b/modules/tgw_gwlb_master/locals.tf
@@ -0,0 +1,62 @@
+locals {
+ regex_valid_vpc_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$"
+ // Will fail if var.vpc_cidr is invalid
+ regex_vpc_cidr = regex(local.regex_valid_vpc_cidr, var.vpc_cidr) == var.vpc_cidr ? 0 : "Variable [vpc_cidr] must be a valid vpc cidr"
+
+ regex_valid_gateway_sic_key = "^[a-zA-Z0-9]{8,}$"
+ // Will fail if var.gateway_SIC_Key is invalid
+ regex_gateway_sic_result = regex(local.regex_valid_gateway_sic_key, var.gateway_SICKey) == var.gateway_SICKey ? 0 : "Variable [gateway_SIC_Key] must be at least 8 alphanumeric characters"
+
+ control_over_public_or_private_allowed_values = [
+ "public",
+ "private"]
+ // will fail if [var.control_gateway_over_public_or_private_address] is invalid:
+ validate_control_over_public_or_private = index(local.control_over_public_or_private_allowed_values, var.gateways_provision_address_type)
+
+ gateway_management_allowed_values = [
+ "Locally managed",
+ "Over the internet"]
+ // will fail if [var.gateway_management] is invalid:
+ validate_gateway_management = index(local.gateway_management_allowed_values, var.gateway_management)
+
+ regex_valid_key_name = "[\\S\\s]+[\\S]+"
+ // will fail if var.key_name is invalid
+ regex_key_name_result=regex(local.regex_valid_key_name, var.key_name) == var.key_name ? 0 : "Variable [key_name] must be a none empty string"
+
+ regex_valid_management_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.management_password_hash is invalid
+ regex_management_password_hash = regex(local.regex_valid_management_password_hash, var.management_password_hash) == var.management_password_hash ? 0 : "Variable [management_password_hash] must be a valid password hash"
+ regex_management_maintenance_mode_password_hash = regex(local.regex_valid_management_password_hash, var.management_maintenance_mode_password_hash) == var.management_maintenance_mode_password_hash ? 0 : "Variable [management_maintenance_mode_password_hash] must be a valid password hash"
+ regex_valid_gateway_password_hash = "^[\\$\\./a-zA-Z0-9]*$"
+ // Will fail if var.gateway_password_hash is invalid
+ regex_gateway_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_password_hash) == var.gateway_password_hash ? 0 : "Variable [gateway_password_hash] must be a valid password hash"
+ regex_gateway_maintenance_mode_password_hash = regex(local.regex_valid_gateway_password_hash, var.gateway_maintenance_mode_password_hash) == var.gateway_maintenance_mode_password_hash ? 0 : "Variable [gateway_maintenance_mode_password_hash] must be a valid password hash"
+
+
+ regex_valid_admin_cidr = "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
+ // Will fail if var.admin_cidr is invalid
+ regex_admin_cidr = regex(local.regex_valid_admin_cidr, var.admin_cidr) == var.admin_cidr ? 0 : "Variable [admin_cidr] must be a valid CIDR"
+
+ regex_valid_gateways_addresses = "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
+ // Will fail if var.gateways_addresses is invalid
+ regex_gateways_addresses = regex(local.regex_valid_gateways_addresses, var.gateways_addresses) == var.gateways_addresses ? 0 : "Variable [gateways_addresses] must be a valid gateways addresses"
+
+ regex_valid_management_server = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.management_server is invalid
+ regex_management_server = regex(local.regex_valid_management_server, var.management_server) == var.management_server ? 0 : "Variable [management_server] can not be an empty string"
+
+ regex_valid_configuration_template = "^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z])?|)$"
+ // Will fail if var.configuration_template is invalid
+ regex_configuration_template = regex(local.regex_valid_configuration_template, var.configuration_template) == var.configuration_template ? 0 : "Variable [configuration_template] can not be an empty string"
+
+ deploy_management_condition = var.management_deploy == true
+
+ volume_type_allowed_values = [
+ "gp3",
+ "gp2"]
+ // will fail if [var.volume_type] is invalid:
+ validate_volume_type = index(local.volume_type_allowed_values, var.volume_type)
+
+
+ #note: we need to add validiation for every subnet in masters solution
+}
\ No newline at end of file
diff --git a/modules/tgw_gwlb_master/main.tf b/modules/tgw_gwlb_master/main.tf
new file mode 100755
index 0000000..a197be7
--- /dev/null
+++ b/modules/tgw_gwlb_master/main.tf
@@ -0,0 +1,77 @@
+module "launch_vpc" {
+ source = "../vpc"
+
+ vpc_cidr = var.vpc_cidr
+ public_subnets_map = var.public_subnets_map
+ private_subnets_map = {}
+ tgw_subnets_map = var.tgw_subnets_map
+ subnets_bit_length = var.subnets_bit_length
+}
+module "tgw_gwlb"{
+ source = "../tgw_gwlb"
+
+ vpc_id = module.launch_vpc.vpc_id
+ gateways_subnets = module.launch_vpc.public_subnets_ids_list
+ number_of_AZs = var.number_of_AZs
+ availability_zones = var.availability_zones
+ internet_gateway_id = module.launch_vpc.aws_igw
+
+ transit_gateway_attachment_subnet_1_id = element(module.launch_vpc.tgw_subnets_ids_list, 0)
+ transit_gateway_attachment_subnet_2_id = element(module.launch_vpc.tgw_subnets_ids_list, 1)
+ transit_gateway_attachment_subnet_3_id = var.number_of_AZs >= 3 ? element(module.launch_vpc.tgw_subnets_ids_list, 2) : ""
+ transit_gateway_attachment_subnet_4_id = var.number_of_AZs >= 4 ? element(module.launch_vpc.tgw_subnets_ids_list, 3) : ""
+
+ nat_gw_subnet_1_cidr = var.nat_gw_subnet_1_cidr
+ nat_gw_subnet_2_cidr = var.nat_gw_subnet_2_cidr
+ nat_gw_subnet_3_cidr = var.nat_gw_subnet_3_cidr
+ nat_gw_subnet_4_cidr = var.nat_gw_subnet_4_cidr
+
+ gwlbe_subnet_1_cidr = var.gwlbe_subnet_1_cidr
+ gwlbe_subnet_2_cidr = var.gwlbe_subnet_2_cidr
+ gwlbe_subnet_3_cidr = var.gwlbe_subnet_3_cidr
+ gwlbe_subnet_4_cidr = var.gwlbe_subnet_4_cidr
+
+ // --- General Settings ---
+ key_name = var.key_name
+ enable_volume_encryption = var.enable_volume_encryption
+ volume_size = var.volume_size
+ enable_instance_connect = var.enable_instance_connect
+ disable_instance_termination = var.disable_instance_termination
+ metadata_imdsv2_required = var.metadata_imdsv2_required
+ allow_upload_download = var.allow_upload_download
+ management_server = var.management_server
+ configuration_template = var.configuration_template
+ admin_shell = var.admin_shell
+
+ // --- Gateway Load Balancer Configuration ---
+ gateway_load_balancer_name = var.gateway_load_balancer_name
+ target_group_name = var.target_group_name
+ enable_cross_zone_load_balancing = var.enable_cross_zone_load_balancing
+
+ // --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+ gateway_name = var.gateway_name
+ gateway_instance_type = var.gateway_instance_type
+ minimum_group_size = var.minimum_group_size
+ maximum_group_size = var.maximum_group_size
+ gateway_version = var.gateway_version
+ gateway_password_hash = var.gateway_password_hash
+ gateway_maintenance_mode_password_hash = var.gateway_maintenance_mode_password_hash
+ gateway_SICKey = var.gateway_SICKey
+ gateways_provision_address_type = var.gateways_provision_address_type
+ allocate_public_IP = var.allocate_public_IP
+ enable_cloudwatch = var.enable_cloudwatch
+ gateway_bootstrap_script = var.gateway_bootstrap_script
+
+ // --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+ management_deploy = var.management_deploy
+ management_instance_type = var.management_instance_type
+ management_version = var.management_version
+ management_password_hash = var.management_password_hash
+ management_maintenance_mode_password_hash = var.management_maintenance_mode_password_hash
+ gateways_policy = var.gateways_policy
+ gateway_management = var.gateway_management
+ admin_cidr = var.admin_cidr
+ gateways_addresses = var.gateways_addresses
+
+ volume_type = var.volume_type
+}
\ No newline at end of file
diff --git a/modules/tgw_gwlb_master/output.tf b/modules/tgw_gwlb_master/output.tf
new file mode 100755
index 0000000..f0f2743
--- /dev/null
+++ b/modules/tgw_gwlb_master/output.tf
@@ -0,0 +1,24 @@
+output "Deployment" {
+ value = "Finalizing instances configuration may take up to 20 minutes after deployment is finished."
+}
+output "management_public_ip" {
+ depends_on = [module.tgw_gwlb]
+ value = module.tgw_gwlb[*].management_public_ip
+}
+output "gwlb_arn" {
+ depends_on = [module.tgw_gwlb]
+ value = module.tgw_gwlb[*].gwlb_arn
+}
+output "gwlb_service_name" {
+ depends_on = [module.tgw_gwlb]
+ value = module.tgw_gwlb[*].gwlb_service_name
+}
+output "gwlb_name" {
+ value = var.gateway_load_balancer_name
+}
+output "controller_name" {
+ value = "gwlb-controller"
+}
+output "template_name" {
+ value = var.configuration_template
+}
\ No newline at end of file
diff --git a/modules/tgw_gwlb_master/variables.tf b/modules/tgw_gwlb_master/variables.tf
new file mode 100755
index 0000000..35afa78
--- /dev/null
+++ b/modules/tgw_gwlb_master/variables.tf
@@ -0,0 +1,310 @@
+// Module: Check Point CloudGuard Network Gateway Load Balancer into an existing VPC
+
+// ---VPC Network Configuration ---
+variable "number_of_AZs" {
+ type = number
+ description = "Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter"
+ default = 2
+}
+variable "availability_zones"{
+ type = list(string)
+ description = "The Availability Zones (AZs) to use for the subnets in the VPC. Select two (the logical order is preserved)"
+}
+resource "null_resource" "tgw_availability_zones_validation1" {
+ count = var.number_of_AZs == length(var.availability_zones) ? 0 : "variable availability_zones list size must be equal to variable num_of_AZs"
+}
+variable "vpc_cidr" {
+ type = string
+ description = "The CIDR block of the VPC"
+ default = "10.0.0.0/16"
+}
+variable "public_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1} ) "
+}
+resource "null_resource" "tgw_availability_zones_validation2" {
+ count = var.number_of_AZs == length(var.public_subnets_map) ? 0 : "variable public_subnets_map size must be equal to variable num_of_AZs"
+}
+variable "subnets_bit_length" {
+ type = number
+ description = "Number of additional bits with which to extend the vpc cidr. For example, if given a vpc_cidr ending in /16 and a subnets_bit_length value of 4, the resulting subnet address will have length /20"
+}
+variable "tgw_subnets_map" {
+ type = map(string)
+ description = "A map of pairs {availability-zone = subnet-suffix-number} for the tgw subnets. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1} ) "
+}
+resource "null_resource" "tgw_availability_zones_validation3" {
+ count = var.number_of_AZs == length(var.tgw_subnets_map) ? 0 : "variable tgw_subnets_map size must be equal to variable num_of_AZs"
+}
+variable "nat_gw_subnet_1_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 1 located in the 1st Availability Zone"
+ default = "10.0.13.0/24"
+}
+variable "nat_gw_subnet_2_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 2 located in the 2st Availability Zone"
+ default = "10.0.23.0/24"
+}
+variable "nat_gw_subnet_3_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 3 located in the 3st Availability Zone"
+ default = "10.0.33.0/24"
+}
+variable "nat_gw_subnet_4_cidr" {
+ type = string
+ description = "CIDR block for NAT subnet 4 located in the 4st Availability Zone"
+ default = "10.0.43.0/24"
+}
+variable "gwlbe_subnet_1_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 1 located in the 1st Availability Zone"
+ default = "10.0.14.0/24"
+}
+variable "gwlbe_subnet_2_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 2 located in the 2st Availability Zone"
+ default = "10.0.24.0/24"
+}
+variable "gwlbe_subnet_3_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 3 located in the 3st Availability Zone"
+ default = "10.0.34.0/24"
+}
+variable "gwlbe_subnet_4_cidr" {
+ type = string
+ description = "CIDR block for Gateway Loadbalancer endpoint subnet 4 located in the 4st Availability Zone"
+ default = "10.0.44.0/24"
+}
+// --- General Settings ---
+variable "key_name" {
+ type = string
+ description = "The EC2 Key Pair name to allow SSH access to the instances"
+}
+variable "enable_volume_encryption" {
+ type = bool
+ description = "Encrypt Environment instances volume with default AWS KMS key"
+ default = true
+}
+variable "volume_size" {
+ type = number
+ description = "Root volume size (GB) - minimum 100"
+ default = 100
+}
+resource "null_resource" "volume_size_too_small" {
+ // Will fail if var.volume_size is less than 100
+ count = var.volume_size >= 100 ? 0 : "variable volume_size must be at least 100"
+}
+variable "volume_type" {
+ type = string
+ description = "General Purpose SSD Volume Type"
+ default = "gp3"
+}
+variable "enable_instance_connect" {
+ type = bool
+ description = "Enable SSH connection over AWS web console"
+ default = false
+}
+variable "disable_instance_termination" {
+ type = bool
+ description = "Prevents an instance from accidental termination"
+ default = false
+}
+variable "metadata_imdsv2_required" {
+ type = bool
+ description = "Set true to deploy the instance with metadata v2 token required"
+ default = true
+}
+variable "allow_upload_download" {
+ type = bool
+ description = "Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point"
+ default = true
+}
+variable "management_server" {
+ type = string
+ description = "The name that represents the Security Management Server in the automatic provisioning configuration."
+ default = "gwlb-management-server"
+}
+variable "configuration_template" {
+ type = string
+ description = "A name of a gateway configuration template in the automatic provisioning configuration."
+ default = "gwlb-ASG-configuration"
+ validation {
+ condition = length(var.configuration_template) < 31
+ error_message = "The configuration_template name can not exceed 30 characters"
+ }
+}
+variable "admin_shell" {
+ type = string
+ description = "Set the admin shell to enable advanced command line configuration"
+ default = "/etc/cli.sh"
+}
+
+// --- Gateway Load Balancer Configuration ---
+
+variable "gateway_load_balancer_name" {
+ type = string
+ description = "Gateway Load Balancer name. This name must be unique within your AWS account and can have a maximum of 32 alphanumeric characters and hyphens. A name cannot begin or end with a hyphen."
+ default = "gwlb1"
+}
+resource "null_resource" "gateway_load_balancer_name_too_long" {
+ // Will fail if gateway_load_balancer_name more than 32
+ count = length(var.gateway_load_balancer_name) <= 32 ? 0 : "variable gateway_load_balancer_name must be at most 32"
+}
+variable "target_group_name" {
+ type = string
+ description = "Target Group Name. This name must be unique within your AWS account and can have a maximum of 32 alphanumeric characters and hyphens. A name cannot begin or end with a hyphen."
+ default = "tg1"
+}
+resource "null_resource" "target_group_name_too_long" {
+ // Will fail if target_group_name more than 32
+ count = length(var.target_group_name) <= 32 ? 0 : "variable target_group_name must be at most 32"
+}
+variable "enable_cross_zone_load_balancing" {
+ type = bool
+ description = "Select 'true' to enable cross-az load balancing. NOTE! this may cause a spike in cross-az charges."
+ default = true
+}
+
+// --- Check Point CloudGuard IaaS Security Gateways Auto Scaling Group Configuration ---
+
+variable "gateway_name" {
+ type = string
+ description = "The name tag of the Security Gateway instances. (optional)"
+ default = "Check-Point-Gateway-tf"
+}
+variable "gateway_instance_type" {
+ type = string
+ description = "The EC2 instance type for the Security Gateways."
+ default = "c6in.xlarge"
+}
+module "validate_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "gateway"
+ instance_type = var.gateway_instance_type
+}
+variable "minimum_group_size" {
+ type = number
+ description = "The minimal number of Security Gateways."
+ default = 2
+}
+variable "maximum_group_size" {
+ type = number
+ description = "The maximal number of Security Gateways."
+ default = 10
+}
+variable "gateway_version" {
+ type = string
+ description = "The version and license to install on the Security Gateways."
+ default = "R81.20-BYOL"
+}
+module "validate_gateway_version" {
+ source = "../version_license"
+
+ chkp_type = "gwlb_gw"
+ version_license = var.gateway_version
+}
+variable "gateway_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "gateway_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the gateway instances, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+variable "gateway_SICKey" {
+ type = string
+ description = "The Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters)"
+}
+
+variable "gateways_provision_address_type" {
+ type = string
+ description = "Determines if the gateways are provisioned using their private or public address"
+ default = "private"
+}
+
+variable "allocate_public_IP" {
+ type = bool
+ description = "Allocate an Elastic IP for security gateway."
+ default = false
+}
+
+resource "null_resource" "invalid_allocation" {
+ // Will fail if var.gateways_provision_address_type is public and var.allocate_public_IP is false
+ count = var.gateways_provision_address_type != "public" ? 0 : var.allocate_public_IP == true ? 0 : "Gateway's selected to be provisioned by public IP, but [allocate_public_IP] parameter is false"
+}
+
+
+variable "enable_cloudwatch" {
+ type = bool
+ description = "Report Check Point specific CloudWatch metrics."
+ default = false
+}
+
+variable "gateway_bootstrap_script" {
+ type = string
+ description = "(Optional) An optional script with semicolon (;) separated commands to run on the initial boot"
+ default = ""
+}
+
+// --- Check Point CloudGuard IaaS Security Management Server Configuration ---
+
+variable "management_deploy" {
+ type = bool
+ description = "Select 'false' to use an existing Security Management Server or to deploy one later and to ignore the other parameters of this section"
+ default = true
+}
+variable "management_instance_type" {
+ type = string
+ description = "The EC2 instance type of the Security Management Server"
+ default = "m5.xlarge"
+}
+module "validate_management_instance_type" {
+ source = "../instance_type"
+
+ chkp_type = "management"
+ instance_type = var.management_instance_type
+}
+variable "management_version" {
+ type = string
+ description = "The license to install on the Security Management Server"
+ default = "R81.20-BYOL"
+}
+module "validate_management_version" {
+ source = "../version_license"
+
+ chkp_type = "management"
+ version_license = var.management_version
+}
+variable "management_password_hash" {
+ type = string
+ description = "(Optional) Admin user's password hash (use command 'openssl passwd -6 PASSWORD' to get the PASSWORD's hash)"
+ default = ""
+}
+variable "management_maintenance_mode_password_hash" {
+ description = "Maintenance mode password hash for the management instance, relevant only for R81.20 and higher versions"
+ type = string
+ default = ""
+}
+variable "gateways_policy" {
+ type = string
+ description = "The name of the Security Policy package to be installed on the gateways in the Security Gateways Auto Scaling group"
+ default = "Standard"
+}
+variable "gateway_management" {
+ type = string
+ description = "Select 'Over the internet' if any of the gateways you wish to manage are not directly accessed via their private IP address."
+ default = "Locally managed"
+}
+variable "admin_cidr" {
+ type = string
+ description = "Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server"
+}
+variable "gateways_addresses" {
+ type = string
+ description = "Allow gateways only from this network to communicate with the Security Management Server"
+}
+
diff --git a/modules/tgw_gwlb_master/versions.tf b/modules/tgw_gwlb_master/versions.tf
new file mode 100755
index 0000000..dbebf27
--- /dev/null
+++ b/modules/tgw_gwlb_master/versions.tf
@@ -0,0 +1,15 @@
+terraform {
+ required_version = ">= 0.14.3"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 5.20.0"
+ }
+ http = {
+ version = "~> 3.4.0"
+ }
+ random = {
+ version = "~> 3.5.1"
+ }
+ }
+}
diff --git a/modules/common/version_license/main.tf b/modules/version_license/main.tf
similarity index 100%
rename from modules/common/version_license/main.tf
rename to modules/version_license/main.tf
diff --git a/modules/common/version_license/variables.tf b/modules/version_license/variables.tf
similarity index 100%
rename from modules/common/version_license/variables.tf
rename to modules/version_license/variables.tf