Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion modules/autoscale/asg_userdata.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +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}\"
python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" installationType=\"autoscale\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.4\" templateName=\"autoscale\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
2 changes: 1 addition & 1 deletion modules/autoscale/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ variable "enable_volume_encryption" {
}
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"
description = "(Optional) A map of tags as key=value pairs. All tags will be added on all Auto Scaling Group instances"
default = {}
}
variable "metadata_imdsv2_required" {
Expand Down
2 changes: 1 addition & 1 deletion modules/autoscale_gwlb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ provider "aws" {}
module "example_module" {

source = "CheckPointSW/cloudguard-network-security/aws//modules/autoscale_gwlb"
version = "1.0.2"
version = "1.0.4"

// --- Environment ---
prefix = "env1"
Expand Down
2 changes: 1 addition & 1 deletion modules/autoscale_gwlb/asg_userdata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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=\"1.0.2\" templateName=\"autoscale_gwlb\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
python3 /etc/cloud_config.py enableCloudWatch=\"${EnableCloudWatch}\" sicKey=\"${SICKey}\" installationType=\"autoscale\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"1.0.4\" templateName=\"autoscale_gwlb\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
2 changes: 1 addition & 1 deletion modules/autoscale_gwlb/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ variable "enable_volume_encryption" {
}
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"
description = "(Optional) A map of tags as key=value pairs. All tags will be added on all Auto Scaling Group instances"
default = {}
}
variable "metadata_imdsv2_required" {
Expand Down
168 changes: 168 additions & 0 deletions modules/autoscale_master/README.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions modules/autoscale_master/asg_userdata.yaml
Original file line number Diff line number Diff line change
@@ -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.4\" templateName=\"autoscale\" templateType=\"terraform_registry\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
66 changes: 66 additions & 0 deletions modules/autoscale_master/locals.tf
Original file line number Diff line number Diff line change
@@ -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"

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"
}
}
279 changes: 279 additions & 0 deletions modules/autoscale_master/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
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
}

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 = module.launch_vpc.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 = module.launch_vpc.public_subnets_ids_list
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 = module.launch_vpc.public_subnets_ids_list
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 = module.launch_vpc.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
}
Loading
Loading