diff --git a/terraform/aws/autoscale-master/README.md b/terraform/aws/autoscale-master/README.md new file mode 100755 index 00000000..37d178f4 --- /dev/null +++ b/terraform/aws/autoscale-master/README.md @@ -0,0 +1,213 @@ +# Check Point CloudGuard Network Auto Scaling Terraform module for AWS + +Terraform module which deploys an Auto Scaling Group of Check Point Security Gateways into a new VPC. + +These types of Terraform resources are supported: +* [Launch template](https://www.terraform.io/docs/providers/aws/r/launch_template.html) +* [VPC](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) +* [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: +- /terraform/aws/modules/amis +- /terraform/aws/modules/vpc + +## Configurations + +The **main.tf** file includes the following provider configuration block used to configure the credentials for the authentication with AWS, as well as a default region for your resources: +``` +provider "aws" { + region = var.region + access_key = var.aws_access_key_ID + secret_key = var.aws_secret_access_key +} +``` +The provider credentials can be provided either as static credentials or as [Environment Variables](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#environment-variables). +- Static credentials can be provided by adding an access_key and secret_key in /terraform/aws/autoscale/**terraform.tfvars** file as follows: +``` +region = "us-east-1" +access_key = "my-access-key" +secret_key = "my-secret-key" +``` +- In case the Environment Variables are used, perform modifications described below:
+ a. The next lines in main.tf file, in the provider aws resource, need to be commented: + ``` + provider "aws" { + // region = var.region + // access_key = var.aws_access_key_ID + // secret_key = var.aws_secret_access_key + } + ``` + +## Usage +- Fill all variables in the /terraform/aws/autoscale/**terraform.tfvars** file with proper values (see below for variables descriptions). +- From a command line initialize the Terraform configuration directory: + ``` + terraform init + ``` +- Create an execution plan: + ``` + terraform plan + ``` +- Create or modify the deployment: + ``` + terraform apply + ``` + +- Variables are configured in /terraform/aws/autoscale/**terraform.tfvars** file as follows: + + ``` + //PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW + + // --- Environment --- + prefix = "env1" + asg_name = "autoscaling_group" + + // --- 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 + + // --- 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" + ``` +- To tear down your resources: + ``` + terraform destroy + ``` + + + +## Inputs +| Name | Description | Type | Allowed values | Default | Required | +|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|----------| +| prefix | (Optional) Instances name prefix | string | n/a | "" | no | +| asg_name | Autoscaling Group name | string | n/a | Check-Point-ASG-tf | no | +| vpc_cidr | The CIDR block of the VPC | string | n/a | 10.0.0.0/16 | no | +| public_subnets_map | A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 1} ) | map(string) | n/a | n/a | yes | +| private_subnets_map | A map of pairs {availability-zone = subnet-suffix-number}. Each entry creates a subnet. Minimum 2 pairs. (e.g. {\"us-east-1a\" = 2} ) | map(string) | n/a | n/a | yes | +| subnets_bit_length | 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 | number | n/a | n/a | yes | +| gateways_provision_address_type | Determines if the gateways are provisioned using their private or public address. | string | - private
- public | private | no | +| management_server | The name that represents the Security Management Server in the CME configuration | string | n/a | n/a | yes | +| configuration_template | Name of the provisioning template in the CME configuration | string | n/a | n/a | yes | +| gateway_name | The name tag of the Security Gateways instances | string | n/a | Check-Point-ASG-gateway-tf | no | +| 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
| c5.xlarge | no | +| key_name | The EC2 Key Pair name to allow SSH access to the instances | string | n/a | n/a | yes | +| volume_size | Root volume size (GB) - minimum 100 | number | n/a | 100 | no | +| enable_volume_encryption | Encrypt Environment instances volume with default AWS KMS key | bool | true/false | true | no | +| instances_tags | (Optional) A map of tags as key=value pairs. All tags will be added on all AutoScaling Group instances | map(string) | n/a | {} | no | +| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false | true | yes | +| minimum_group_size | The minimum number of instances in the Auto Scaling group | number | n/a | 2 | no | +| maximum_group_size | The maximum number of instances in the Auto Scaling group | number | n/a | 10 | no | +| target_groups | (Optional) List of Target Group ARNs to associate with the Auto Scaling group | list(string) | n/a | [] | no | +| 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 | R81.20-BYOL | no | +| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh | /etc/cli.sh | no | +| gateway_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). (optional) | string | n/a | "" | no | +| gateway_SICKey | The Secure Internal Communication key for trusted connection between Check Point components (at least 8 alphanumeric characters) | string | n/a | "12345678" | yes | +| 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 | false | no | +| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false | true | no | +| enable_cloudwatch | Report Check Point specific CloudWatch metrics | bool | true/false | false | no | +| gateway_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | n/a | "" | no | +| proxy_elb_type | Type of ELB to create as an HTTP/HTTPS outbound proxy | string | - none
- internal
- internet-facing | none | no | +| proxy_elb_port | The TCP port on which the proxy will be listening | number | n/a | 8080 | no | +| proxy_elb_clients | The CIDR range of the clients of the proxy | string | n/a | 0.0.0.0/0 | no | +| 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 | n/a | "" | no | + + +## Outputs +| 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) | + +## Revision History +In order to check the template version, please refer to [sk116585](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk116585) + +| Template Version | Description | +|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 20240704 | - R80.40 version deprecation.
- R81 version deprecation. | +| 20240417 | - Add support for Elastic Load Balancer Health Checks.
- EC2 Auto Scaling will start to detect and act on health checks performed by Elastic Load Balancing. | +| 20240310 | Add support for requiring use instance metadata service version 2 (IMDSv2) only | +| 20231012 | Update AWS Terraform provider version to 5.20.1 | +| 20230923 | Add support for C5d instance type | +| 20230914 | Add support for maintenance mode password | +| 20230829 | Change default Check Point version to R81.20 | +| 20230806 | Add support for c6in instance type | +| 20230521 | Change default shell for the admin user to /etc/cli.sh | +| 20221226 | Support ASG Launch Template instead of Launch Configuration | +| 20221123 | R81.20 version support | +| 20220606 | New instance type support | +| 20210329 | Stability fixes | +| 20210309 | AWS Terraform modules refactor | +| 20200318 | First release of Check Point Auto Scaling Terraform module for AWS | + + +## License + +This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details diff --git a/terraform/aws/autoscale-master/asg_userdata.yaml b/terraform/aws/autoscale-master/asg_userdata.yaml new file mode 100755 index 00000000..4c6633c3 --- /dev/null +++ b/terraform/aws/autoscale-master/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=\"20240704\" templateName=\"autoscale\" templateType=\"terraform\" shell=\"${Shell}\" enableInstanceConnect=\"${EnableInstanceConnect}\" passwordHash=\"${PasswordHash}\" MaintenanceModePassword=\"${MaintenanceModePassword}\" bootstrapScript64=\"${BootstrapScript}\" diff --git a/terraform/aws/autoscale-master/locals.tf b/terraform/aws/autoscale-master/locals.tf new file mode 100755 index 00000000..4fa533c0 --- /dev/null +++ b/terraform/aws/autoscale-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" + + 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/terraform/aws/autoscale-master/main.tf b/terraform/aws/autoscale-master/main.tf new file mode 100755 index 00000000..03877cb4 --- /dev/null +++ b/terraform/aws/autoscale-master/main.tf @@ -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 +} diff --git a/terraform/aws/autoscale-master/output.tf b/terraform/aws/autoscale-master/output.tf new file mode 100755 index 00000000..152bb744 --- /dev/null +++ b/terraform/aws/autoscale-master/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/terraform/aws/autoscale-master/terraform.tfvars b/terraform/aws/autoscale-master/terraform.tfvars new file mode 100755 index 00000000..18722ab6 --- /dev/null +++ b/terraform/aws/autoscale-master/terraform.tfvars @@ -0,0 +1,53 @@ +//PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW + +// --- Environment --- +prefix = "env1" +asg_name = "autoscaling_group" + +// --- 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 + +// --- 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 = "c6in.xlarge" +key_name = "publickey" +instances_tags = { + key1 = "value1" + key2 = "value2" +} +metadata_imdsv2_required = true + +// --- 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 diff --git a/terraform/aws/autoscale-master/variables.tf b/terraform/aws/autoscale-master/variables.tf new file mode 100755 index 00000000..21ea8497 --- /dev/null +++ b/terraform/aws/autoscale-master/variables.tf @@ -0,0 +1,209 @@ +// Module: Check Point CloudGuard Network Auto Scaling Group into an existing VPC + +// --- AWS Provider --- +variable "region" { + type = string + description = "AWS region" + default = "" +} +variable "access_key" { + type = string + description = "AWS access key" + default = "" +} +variable "secret_key" { + type = string + description = "AWS secret key" + default = "" +} + +// --- 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-Security-Gateway-AutoScaling-Group-tf" + validation { + condition = length(var.asg_name) <= 100 + error_message = "Autoscaling Group name can not exceed 100 characters." + } +} + +// --- 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 "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" +} + +// --- 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 = "../modules/common/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 = "../modules/common/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" +} diff --git a/terraform/aws/autoscale-master/versions.tf b/terraform/aws/autoscale-master/versions.tf new file mode 100755 index 00000000..dbebf275 --- /dev/null +++ b/terraform/aws/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/terraform/aws/management-master/README.md b/terraform/aws/management-master/README.md new file mode 100755 index 00000000..04956da3 --- /dev/null +++ b/terraform/aws/management-master/README.md @@ -0,0 +1,205 @@ +# Check Point CloudGuard Network Security Management Server Terraform module for AWS + +Terraform module which deploys a Check Point CloudGuard Network Security Management Server 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://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) +* [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 +* [IAM Role](https://www.terraform.io/docs/providers/aws/r/iam_role.html) - conditional creation + +See the [Security Management Server with CloudGuard for AWS](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk130372) for additional information + +This solution uses the following modules: +- /terraform/aws/modules/amis +- /terraform/aws/cme-iam-role +- /terraform/aws/modules/vpc + +## Configurations + +The **main.tf** file includes the following provider configuration block used to configure the credentials for the authentication with AWS, as well as a default region for your resources: +``` +provider "aws" { + region = var.region + access_key = var.access_key + secret_key = var.secret_key +} +``` +The provider credentials can be provided either as static credentials or as [Environment Variables](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#environment-variables). +- Static credentials can be provided by adding an access_key and secret_key in /terraform/aws/management/**terraform.tfvars** file as follows: +``` +region = "us-east-1" +access_key = "my-access-key" +secret_key = "my-secret-key" +``` +- In case the Static credentials are used, perform modifications described below:
+ a. The next lines in main.tf file, in the provider aws resource, need to be commented for sub-module /terraform/aws/cme-iam-role: + ``` + provider "aws" { + // region = var.region + // access_key = var.access_key + // secret_key = var.secret_key + } + ``` +- In case the Environment Variables are used, perform modifications described below:
+ a. The next lines in main.tf file, in the provider aws resource, need to be commented: + ``` + provider "aws" { + // region = var.region + // access_key = var.access_key + // secret_key = var.secret_key + } + ``` + b. The next lines in main.tf file, in the provider aws resource, need to be commented for sub-module /terraform/aws/cme-iam-role: + ``` + provider "aws" { + // region = var.region + // access_key = var.access_key + // secret_key = var.secret_key + } + ``` + +## Usage +- Fill all variables in the /terraform/aws/management/**terraform.tfvars** file with proper values (see below for variables descriptions). +- From a command line initialize the Terraform configuration directory: + ``` + terraform init + ``` +- Create an execution plan: + ``` + terraform plan + ``` +- Create or modify the deployment: + ``` + terraform apply + ``` + +- Variables are configured in /terraform/aws/management/**terraform.tfvars** file as follows: + + ``` + //PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW + + // --- VPC Network Configuration --- + vpc_cidr = "10.0.0.0/16" + public_subnet_az = "eu-north-1a" + subnets_bit_length = 8 + + // --- 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" + ``` + +- Conditional creation + - To create an Elastic IP and associate it to the Management instance: + ``` + allocate_and_associate_eip = true + ``` + - 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)" + ``` +- To tear down your resources: + ``` + terraform destroy + ``` + +## Inputs +| Name | Description | Type | Allowed values | Default | Required | +|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|----------| +| vpc_cidr | The CIDR block of the VPC | string | n/a | 10.0.0.0/16 | no | +| public_subnet_az | The availability-zone for the public subnet. ( e.g. \"us-east-1a\" ) | string | n/a | n/a | yes | +| subnets_bit_length | 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. | number | n/a | n/a | yes | +| management_name | (Optional) The name tag of the Security Management instance | string | n/a | Check-Point-Management-tf | no | +| 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
| m5.xlarge | no | +| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | n/a | n/a | yes | +| allocate_and_associate_eip | If set to true, an elastic IP will be allocated and associated with the launched instance | bool | true/false | true | yes | +| volume_size | Root volume size (GB) - minimum 100 | number | n/a | 100 | no | +| 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 | n/a | alias/aws/ebs | no | +| 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 | false | no | +| disable_instance_termination | Prevents an instance from accidental termination. Note: Once this attribute is true terraform destroy won't work properly | bool | true/false | false | no | +| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false | true | yes | +| instance_tags | (Optional) A map of tags as key=value pairs. All tags will be added to the Management EC2 Instance | map(string) | n/a | {} | no | +| iam_permissions | IAM role to attach to the instance profile | string | - 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 | Create with read permissions | no | +| predefined_role | (Optional) A predefined IAM role to attach to the instance profile. Ignored if var.iam_permissions is not set to 'Use existing' | string | n/a | "" | no | +| sts_roles | (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' | list(string) | n/a | [] | no | +| management_version | Management version and license | string | - R81.10-BYOL
- R81.10-PAYG
- R81.20-BYOL
- R81.20-PAYG
- R82-BYOL
- R82-PAYG | R81.20-BYOL | no | +| admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh | /etc/cli.sh | no | +| management_password_hash | (Optional) Admin user's password hash (use command "openssl passwd -6 PASSWORD" to get the PASSWORD's hash) | string | n/a | "" | no | +| management_hostname | (Optional) Security Management Server prompt hostname. The name must not contain reserved words. For details, refer to sk40179. | string | n/a | "" | no | +| management_installation_type | Determines if this is the primary management server, secondary management server or log server | string | - Primary management
- Secondary management
- Log Server
| Primary management | yes | +| SICKey | Mandatory only when deploying a secondary Management Server, the Secure Internal Communication key creates trusted connections between Check Point components. Choose a random string consisting of at least 8 alphanumeric characters | string | n/a | "" | no | +| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false | true | no | +| 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 | Locally managed | no | +| admin_cidr | (CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Security Management Server | string | valid CIDR | 0.0.0.0/0 | no | +| gateway_addresses | (CIDR) Allow gateways only from this network to communicate with the Security Management Server | string | valid CIDR | 0.0.0.0/0 | no | +| primary_ntp | (Optional) The IPv4 addresses of Network Time Protocol primary server | string | n/a | 169.254.169.123 | no | +| secondary_ntp | (Optional) The IPv4 addresses of Network Time Protocol secondary server | string | n/a | 0.pool.ntp.org | no | +| management_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | n/a | "" | no | +| 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). (optional) | string | n/a | "" | no | + + +## Outputs +| Name | Description | +|--------------------------|--------------------------------------------------------------| +| management_instance_id | The deployed Security Management Server AWS instance id | +| management_instance_name | The deployed Security Management AWS instance name | +| management_instance_tags | The deployed Security Management Server AWS tags | +| management_public_ip | The deployed Security Management Server AWS public ip | +| management_url | URL to the portal of the deployed Security Management Server | + +## Revision History +In order to check the template version, please refer to [sk116585](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk116585) + +| Template Version | Description | +|------------------|---------------------------------------------------------------------------------------------------------------| +| 20240704 | - R80.40 version deprecation.
- R81 version deprecation. | +| 20240310 | Add support for requiring use instance metadata service version 2 (IMDSv2) only | +| 20240207 | Added Log Server installation support | +| 20231012 | Update AWS Terraform provider version to 5.20.1 | +| 20230923 | Add support for C5d instance type | +| 20230914 | Add support for maintenance mode password | +| 20230829 | Change default Check Point version to R81.20 | +| 20230806 | Add support for c6in instance type | +| 20230521 | - Change default shell for the admin user to /etc/cli.sh
- Add description for reserved words in hostname | +| 20221123 | R81.20 version support | +| 20220606 | New instance type support | +| 20210329 | Stability fixes | +| 20210309 | First release of Check Point Security Management Server Terraform module for AWS | + +## License + +This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details diff --git a/terraform/aws/management-master/locals.tf b/terraform/aws/management-master/locals.tf new file mode 100755 index 00000000..945041a7 --- /dev/null +++ b/terraform/aws/management-master/locals.tf @@ -0,0 +1,80 @@ +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.permissions is invalid + validate_permissions = index(local.permissions_allowed_values, var.iam_permissions) + + use_role = var.iam_permissions == "None (configure later)" ? 0 : 1 + create_iam_role = 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" + pre_role = (local.use_role == 1 && local.create_iam_role == false) ? 1 : 0 + new_instance_profile = (local.create_iam_role == true && local.use_role == 1) ? 1 : 0 + + new_instance_profile_general = local.new_instance_profile == 1 && var.is_gwlb_iam == false ? 1 : 0 + new_instance_profile_gwlb = local.new_instance_profile == 1 && var.is_gwlb_iam ? 1 : 0 + + 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" + + 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_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_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_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_sic_key = "(|[a-zA-Z0-9]{8,})" + // Will fail if var.SICKey is invalid + regex_sic_result = regex(local.regex_valid_sic_key, var.SICKey) == var.SICKey ? 0 : "Variable [SICKey] must be at least 8 alphanumeric characters" + + //Splits the version and licence and returns the os version + version_split = element(split("-", var.management_version), 0) + + management_bootstrap_script64 = base64encode(var.management_bootstrap_script) + management_SICkey_base64=base64encode(var.SICKey) + management_password_hash_base64=base64encode(var.management_password_hash) + maintenance_mode_password_hash_base64=base64encode(var.management_maintenance_mode_password_hash) + + manage_over_the_internet = var.gateway_management == "Over the internet" ? true : false + manage_over_internet_and_EIP = var.allocate_and_associate_eip && local.manage_over_the_internet ? true : false + pub_mgmt = local.manage_over_internet_and_EIP ? true : false + + management_installation_type_allowed_values = [ + "Primary management", + "Secondary management", + "Log Server"] + validate_management_installation_type = index(local.management_installation_type_allowed_values, var.management_installation_type) +} \ No newline at end of file diff --git a/terraform/aws/management-master/main.tf b/terraform/aws/management-master/main.tf new file mode 100755 index 00000000..c15c44e2 --- /dev/null +++ b/terraform/aws/management-master/main.tf @@ -0,0 +1,233 @@ +provider "aws" { + region = var.region + access_key = var.access_key + secret_key = var.secret_key +} + +// --- VPC --- +module "launch_vpc" { + source = "../modules/vpc" + + vpc_cidr = var.vpc_cidr + public_subnets_map = { + (var.public_subnet_az) = 1 + } + private_subnets_map = {} + subnets_bit_length = var.subnets_bit_length +} + +module "amis" { + source = "../modules/amis" + + version_license = var.management_version + chkp_type = "management" +} + +resource "aws_security_group" "management_sg" { + description = "terraform Management security group" + vpc_id = module.launch_vpc.vpc_id + name_prefix = format("%s_SecurityGroup", var.management_name) + // Group name + tags = { + Name = format("%s_SecurityGroup", var.management_name) + // Resource name + } + ingress { + from_port = 257 + to_port = 257 + 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] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "external-eni" { + subnet_id = module.launch_vpc.public_subnets_ids_list[0] + security_groups = [aws_security_group.management_sg.id] + description = "eth0" + source_dest_check = true + tags = { + Name = format("%s-network_interface", var.management_name) + } +} + +resource "aws_eip" "eip" { + count = var.allocate_and_associate_eip ? 1 : 0 + network_interface = aws_network_interface.external-eni.id +} + +resource "aws_iam_instance_profile" "management_instance_profile" { + count = local.pre_role + path = "/" + role = var.predefined_role +} + +resource "aws_launch_template" "management_launch_template" { + depends_on = [ + aws_network_interface.external-eni, + aws_eip.eip + ] + + instance_type = var.management_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 ? (local.pre_role == 1 ? aws_iam_instance_profile.management_instance_profile[0].id : join("", (var.is_gwlb_iam == true ? module.cme_iam_role_gwlb.*.cme_iam_profile_name : module.cme_iam_role.*.cme_iam_profile_name))): "" + } + + 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" "management-instance" { + depends_on = [ + aws_launch_template.management_launch_template + ] + + launch_template { + id = aws_launch_template.management_launch_template.id + version = "$Latest" + } + + disable_api_termination = var.disable_instance_termination + + tags = merge({ + Name = var.management_name + }, var.instance_tags) + + ebs_block_device { + device_name = "/dev/xvda" + volume_type = var.volume_type + 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}/management_userdata.yaml", { + // script's arguments + Hostname = var.management_hostname, + PasswordHash = local.management_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.admin_shell, + AdminSubnet = var.admin_cidr + ManagementInstallationType = var.management_installation_type + SICKey = local.management_SICkey_base64, + OsVersion = local.version_split + EnableInstanceConnect = var.enable_instance_connect + AllocateElasticIP = var.allocate_and_associate_eip + GatewayManagement = var.gateway_management + BootstrapScript = local.management_bootstrap_script64 + PubMgmt = local.pub_mgmt + + }) +} + +module "cme_iam_role" { + source = "../cme-iam-role" + providers = { + aws = aws + } + count = local.new_instance_profile_general + + sts_roles = var.sts_roles + permissions = var.iam_permissions +} + +module "cme_iam_role_gwlb" { + source = "../cme-iam-role-gwlb" + providers = { + aws = aws + } + count = local.new_instance_profile_gwlb + + sts_roles = var.sts_roles + permissions = var.iam_permissions +} diff --git a/terraform/aws/management-master/management_userdata.yaml b/terraform/aws/management-master/management_userdata.yaml new file mode 100755 index 00000000..cfd9e5dc --- /dev/null +++ b/terraform/aws/management-master/management_userdata.yaml @@ -0,0 +1,4 @@ +#cloud-config +runcmd: + - | + python3 /etc/cloud_config.py sicKey=\"${SICKey}\" installationType=\"management\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"20240704\" 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 diff --git a/terraform/aws/management-master/output.tf b/terraform/aws/management-master/output.tf new file mode 100755 index 00000000..da20727b --- /dev/null +++ b/terraform/aws/management-master/output.tf @@ -0,0 +1,19 @@ +output "Deployment" { + value = "Finalizing configuration may take up to 20 minutes after deployment is finished." +} + +output "management_instance_id" { + value = aws_instance.management-instance.id +} +output "management_instance_name" { + value = aws_instance.management-instance.tags["Name"] +} +output "management_instance_tags" { + value = aws_instance.management-instance.tags +} +output "management_public_ip" { + value = aws_instance.management-instance.public_ip +} +output "management_url" { + value = format("https://%s", aws_instance.management-instance.public_ip) +} \ No newline at end of file diff --git a/terraform/aws/management-master/terraform.tfvars b/terraform/aws/management-master/terraform.tfvars new file mode 100755 index 00000000..9f426131 --- /dev/null +++ b/terraform/aws/management-master/terraform.tfvars @@ -0,0 +1,43 @@ +//PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW + +// --- VPC Network Configuration --- +vpc_cidr = "10.0.0.0/16" +public_subnet_az = "us-east-1a" +subnets_bit_length = 8 + +// --- 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 +metadata_imdsv2_required = true +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" diff --git a/terraform/aws/management-master/variables.tf b/terraform/aws/management-master/variables.tf new file mode 100755 index 00000000..7bdca0ff --- /dev/null +++ b/terraform/aws/management-master/variables.tf @@ -0,0 +1,200 @@ +// Module: Check Point CloudGuard Network Security Management Server into an existing VPC + +// --- AWS Provider --- +variable "region" { + type = string + description = "AWS region" + default = "" +} +variable "access_key" { + type = string + description = "AWS access key" + default = "" +} +variable "secret_key" { + type = string + description = "AWS secret key" + default = "" +} + +// --- VPC Network Configuration --- +variable "vpc_cidr" { + type = string + description = "The CIDR block of the VPC" + default = "10.0.0.0/16" +} +variable "public_subnet_az" { + type = string + description = "The availability-zone for the public subnet. ( e.g. \"us-east-1a\" )" +} +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 "management_name" { + type = string + description = "(Optional) The name tag of the Security Management instance" + default = "Check-Point-Management-tf" +} +variable "management_instance_type" { + type = string + description = "The instance type of the Security Management Server" + default = "m5.xlarge" +} +module "validate_instance_type" { + source = "../modules/common/instance_type" + + chkp_type = "management" + instance_type = var.management_instance_type +} +variable "key_name" { + type = string + description = "The EC2 Key Pair name to allow SSH access to the instances" +} +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" { + // 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 AWS Instance Connect - Ec2 Instance Connect is not supported with versions prior to R80.40" + 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 Management EC2 Instance" + default = {} +} + +// --- IAM Permissions (ignored when the installation is not Primary Management 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 "management_version" { + type = string + description = "Management version and license" + default = "R81.20-BYOL" +} +module "validate_management_version" { + source = "../modules/common/version_license" + + chkp_type = "management" + version_license = var.management_version +} +variable "admin_shell" { + type = string + description = "Set the admin shell to enable advanced command line configuration" + default = "/etc/cli.sh" +} +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 = "" +} + +// --- Security Management Server Settings --- +variable "management_hostname" { + type = string + description = "(Optional) Security Management Server prompt hostname" + default = "" +} +variable "management_installation_type" { + type = string + description = "Determines the Management Server installation type: Primary management, Secondary management, Log Server" + default = "Primary management" +} +variable "SICKey" { + type = string + description = "Mandatory only when deploying a secondary Management 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 "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 = "(CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Security 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 Security Management 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 "management_bootstrap_script" { + type = string + description = "(Optional) Semicolon (;) separated commands to run on the initial boot" + default = "" +} +variable "volume_type" { + type = string + description = "General Purpose SSD Volume Type" + default = "gp3" +} +variable "is_gwlb_iam" { + type = bool + default = false +} \ No newline at end of file diff --git a/terraform/aws/management-master/versions.tf b/terraform/aws/management-master/versions.tf new file mode 100755 index 00000000..c138bbb3 --- /dev/null +++ b/terraform/aws/management-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/terraform/aws/mds-master/README.md b/terraform/aws/mds-master/README.md new file mode 100755 index 00000000..e0ef2d5c --- /dev/null +++ b/terraform/aws/mds-master/README.md @@ -0,0 +1,195 @@ +# Check Point CloudGuard Network Multi-Domain Server Terraform module for AWS + +Terraform module which deploys a Check Point CloudGuard Network Multi-Domain Server 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://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) +* [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: +- /terraform/aws/modules/amis +- /terraform/aws/cme-iam-role +- /terraform/aws/modules/vpc + +## Configurations + +The **main.tf** file includes the following provider configuration block used to configure the credentials for the authentication with AWS, as well as a default region for your resources: +``` +provider "aws" { + region = var.region + access_key = var.access_key + secret_key = var.secret_key +} +``` +The provider credentials can be provided either as static credentials or as [Environment Variables](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#environment-variables). +- Static credentials can be provided by adding an access_key and secret_key in /terraform/aws/mds/**terraform.tfvars** file as follows: +``` +region = "us-east-1" +access_key = "my-access-key" +secret_key = "my-secret-key" +``` +- In case the Static credentials are used, perform modifications described below:
+ a. The next lines in main.tf file, in the provider aws resource, need to be commented for sub-module /terraform/aws/cme-iam-role: + ``` + provider "aws" { + // region = var.region + // access_key = var.access_key + // secret_key = var.secret_key + } + ``` +- In case the Environment Variables are used, perform modifications described below:
+ a. The next lines in main.tf file, in the provider aws resource, need to be commented: + ``` + provider "aws" { + // region = var.region + // access_key = var.access_key + // secret_key = var.secret_key + } + ``` + b. The next lines in main.tf file, in the provider aws resource, need to be commented for sub-module /terraform/aws/cme-iam-role: + ``` + provider "aws" { + // region = var.region + // access_key = var.access_key + // secret_key = var.secret_key + } + ``` + +## Usage +- Fill all variables in the /terraform/aws/mds/**terraform.tfvars** file with proper values (see below for variables descriptions). +- From a command line initialize the Terraform configuration directory: + ``` + terraform init + ``` +- Create an execution plan: + ``` + terraform plan + ``` +- Create or modify the deployment: + ``` + terraform apply + ``` + +- Variables are configured in /terraform/aws/mds/**terraform.tfvars** file as follows: + + ``` + //PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW + + // --- VPC Network Configuration --- + vpc_cidr = "10.0.0.0/16" + public_subnet_az = "eu-north-1a" + subnets_bit_length = 8 + + // --- 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" + ``` +- To tear down your resources: + ``` + terraform destroy + ``` + +## Inputs +| Name | Description | Type | Allowed values | Default | Required | +|------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|----------| +| vpc_cidr | The CIDR block of the VPC | string | n/a | 10.0.0.0/16 | no | +| public_subnet_az | The availability-zone for the public subnet. ( e.g. \"us-east-1a\" ) | string | n/a | n/a | yes | +| subnets_bit_length | 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 | number | n/a | n/a | yes | +| mds_name | (Optional) The name tag of the Multi-Domain Server instance | string | n/a | Check-Point-MDS-tf | no | +| mds_instance_type | The instance type of the Multi-Domain 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
| m5.12xlarge | no | +| key_name | The EC2 Key Pair name to allow SSH access to the instance | string | n/a | n/a | yes | +| volume_size | Root volume size (GB) - minimum 100 | number | n/a | 100 | no | +| 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 | n/a | alias/aws/ebs | no | +| 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 | false | no | +| disable_instance_termination | Prevents an instance from accidental termination. Note: Once this attribute is true terraform destroy won't work properly | bool | true/false | false | no | +| instance_tags | (Optional) A map of tags as key=value pairs. All tags will be added to the Multi-Domain Server EC2 Instance | map(string) | n/a | {} | no | +| metadata_imdsv2_required | Set true to deploy the instance with metadata v2 token required | bool | true/false | true | yes | +| iam_permissions | IAM role to attach to the instance profile | string | - 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 | Create with read permissions | no | +| predefined_role | (Optional) A predefined IAM role to attach to the instance profile. Ignored if var.iam_permissions is not set to 'Use existing' | string | n/a | "" | no | +| sts_roles | (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' | list(string) | n/a | [] | no | +| mds_version | Multi-Domain Server version and license | string | - R81.20-BYOL
- R82-BYOL
- R82-PAYG | R81.20-BYOL | no | +| mds_admin_shell | Set the admin shell to enable advanced command line configuration | string | - /etc/cli.sh
- /bin/bash
- /bin/csh
- /bin/tcsh | /etc/cli.sh | no | +| mds_password_hash | (Optional) Admin user's password hash (use command "openssl passwd -6 PASSWORD" to get the PASSWORD's hash) | string | n/a | "" | no | +| mds_hostname | (Optional) Multi-Domain Server prompt hostname. The name must not contain reserved words. For details, refer to sk40179. | string | n/a | "" | no | +| mds_SICKey | 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 | string | n/a | "" | no | +| allow_upload_download | Automatically download Blade Contracts and other important data. Improve product experience by sending data to Check Point | bool | true/false | true | no | +| mds_installation_type | Determines the Multi-Domain Server installation type | string | - Primary Multi-Domain Server
- Secondary Multi-Domain Server
- Multi-Domain Log Server | Primary Multi-Domain Server | no | +| admin_cidr | (CIDR) Allow web, ssh, and graphical clients only from this network to communicate with the Multi-Domain Server | string | valid CIDR | 0.0.0.0/0 | no | +| gateway_addresses | (CIDR) Allow gateways only from this network to communicate with the Multi-Domain Server | string | valid CIDR | 0.0.0.0/0 | no | +| primary_ntp | (Optional) The IPv4 addresses of Network Time Protocol primary server | string | n/a | 169.254.169.123 | no | +| secondary_ntp | (Optional) The IPv4 addresses of Network Time Protocol secondary server | string | n/a | 0.pool.ntp.org | no | +| mds_bootstrap_script | (Optional) Semicolon (;) separated commands to run on the initial boot | string | n/a | "" | no | +| mds_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 | n/a | "" | no | + + +## Outputs +| 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 | + +## Revision History +In order to check the template version, please refer to [sk116585](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk116585) + +| Template Version | Description | +|------------------|---------------------------------------------------------------------------------------------------------------| +| 20240704 | - R80.40 version deprecation.
- R81 version deprecation. | +| 20240310 | Add support for requiring use instance metadata service version 2 (IMDSv2) only | +| 20231012 | Update AWS Terraform provider version to 5.20.1 | +| 20230923 | Add support for C5d instance type | +| 20230914 | Add support for maintenance mode password | +| 20230829 | Change default Check Point version to R81.20 | +| 20230806 | Add support for c6in instance type | +| 20230521 | - Change default shell for the admin user to /etc/cli.sh
- Add description for reserved words in hostname | +| 20221123 | R81.20 version support | +| 20210329 | Stability fixes | +| 20210309 | First release of Check Point Multi-Domain Server Terraform module for AWS | + +## License + +This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details diff --git a/terraform/aws/mds-master/locals.tf b/terraform/aws/mds-master/locals.tf new file mode 100755 index 00000000..651846d5 --- /dev/null +++ b/terraform/aws/mds-master/locals.tf @@ -0,0 +1,73 @@ +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.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/terraform/aws/mds-master/main.tf b/terraform/aws/mds-master/main.tf new file mode 100755 index 00000000..17078038 --- /dev/null +++ b/terraform/aws/mds-master/main.tf @@ -0,0 +1,206 @@ +provider "aws" { + region = var.region + access_key = var.access_key + secret_key = var.secret_key +} + +// --- VPC --- +module "launch_vpc" { + source = "../modules/vpc" + + vpc_cidr = var.vpc_cidr + public_subnets_map = { + (var.public_subnet_az) = 1 + } + private_subnets_map = {} + subnets_bit_length = var.subnets_bit_length +} + +module "amis" { + source = "../modules/amis" + + version_license = var.mds_version + chkp_type = "mds" +} + +resource "aws_security_group" "mds_sg" { + description = "terraform Multi-Domain Server security group" + vpc_id = module.launch_vpc.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] + } + + egress { + 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 = module.launch_vpc.public_subnets_ids_list[0] + 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" + providers = { + aws = aws + } + count = local.create_iam_role ? 1 : 0 + + sts_roles = var.sts_roles + permissions = var.iam_permissions +} diff --git a/terraform/aws/mds-master/mds_userdata.yaml b/terraform/aws/mds-master/mds_userdata.yaml new file mode 100755 index 00000000..cd0085c6 --- /dev/null +++ b/terraform/aws/mds-master/mds_userdata.yaml @@ -0,0 +1,4 @@ +#cloud-config +runcmd: + - | + python3 /etc/cloud_config.py sicKey=\"${SICKey}\" installationType=\"mds\" osVersion=\"${OsVersion}\" allowUploadDownload=\"${AllowUploadDownload}\" templateVersion=\"20240704\" templateName=\"mds\" templateType=\"terraform\" 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/terraform/aws/mds-master/output.tf b/terraform/aws/mds-master/output.tf new file mode 100755 index 00000000..c1d3783a --- /dev/null +++ b/terraform/aws/mds-master/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/terraform/aws/mds-master/terraform.tfvars b/terraform/aws/mds-master/terraform.tfvars new file mode 100755 index 00000000..252fc139 --- /dev/null +++ b/terraform/aws/mds-master/terraform.tfvars @@ -0,0 +1,42 @@ +//PLEASE refer to README.md for accepted values FOR THE VARIABLES BELOW + +// --- VPC Network Configuration --- +vpc_cidr = "10.0.0.0/16" +public_subnet_az = "us-east-1a" +subnets_bit_length = 8 + +// --- 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 +metadata_imdsv2_required = true +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" diff --git a/terraform/aws/mds-master/variables.tf b/terraform/aws/mds-master/variables.tf new file mode 100755 index 00000000..f38acd30 --- /dev/null +++ b/terraform/aws/mds-master/variables.tf @@ -0,0 +1,181 @@ +// Module: Check Point CloudGuard Network Multi-Domain Server into an existing VPC + +// --- AWS Provider --- +variable "region" { + type = string + description = "AWS region" + default = "" +} +variable "access_key" { + type = string + description = "AWS access key" + default = "" +} +variable "secret_key" { + type = string + description = "AWS secret key" + default = "" +} + +// --- VPC Network Configuration --- +variable "vpc_cidr" { + type = string + description = "The CIDR block of the VPC" + default = "10.0.0.0/16" +} +variable "public_subnet_az" { + type = string + description = "The availability-zone for the public subnet. ( e.g. \"us-east-1a\" )" +} +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 "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 = "../modules/common/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 = "../modules/common/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 = "" +} diff --git a/terraform/aws/mds-master/versions.tf b/terraform/aws/mds-master/versions.tf new file mode 100755 index 00000000..c138bbb3 --- /dev/null +++ b/terraform/aws/mds-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" + } + } +}