Skip to content

Commit

Permalink
Merge pull request #460 from CheckPointSW/cloudguard-integrations-clo…
Browse files Browse the repository at this point in the history
…udguardiaas-0b6d89d43aa52e8a90bf45cb2361c62f38ac3c9e

Add new AWS master Terraform templates for Management, MDS, and Autoscale
  • Loading branch information
chkp-noamcoh authored Dec 18, 2024
2 parents 8724be7 + e8521e0 commit ec11c39
Show file tree
Hide file tree
Showing 24 changed files with 2,382 additions and 0 deletions.
213 changes: 213 additions & 0 deletions terraform/aws/autoscale-master/README.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions terraform/aws/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=\"20240704\" templateName=\"autoscale\" templateType=\"terraform\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\"
66 changes: 66 additions & 0 deletions terraform/aws/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"
}
}
257 changes: 257 additions & 0 deletions terraform/aws/autoscale-master/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}

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 "amis" {
source = "../modules/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
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"]
}
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 = "../modules/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
}
43 changes: 43 additions & 0 deletions terraform/aws/autoscale-master/output.tf
Original file line number Diff line number Diff line change
@@ -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
}

Loading

0 comments on commit ec11c39

Please sign in to comment.