# Some instance variables locals { ami_selection = "minion" # master, minion, ... } # Rather than pass in the aws security group, we just look it up. This will # probably be useful other places, as well. data "aws_security_group" "typical-host" { name = "typical-host" vpc_id = var.vpc_id } # Use the default EBS key data "aws_kms_key" "ebs-key" { key_id = "alias/ebs_root_encrypt_decrypt" } #------------------------------------ # EC2 ASG #------------------------------------ resource "aws_launch_template" "customer_portal" { name = "customer-portal-lt" instance_type = "t3a.medium" image_id = local.ami_map[local.ami_selection] user_data = data.template_cloudinit_config.cloud-init.rendered ebs_optimized = true tags = merge(local.standard_tags, var.instance_tags, var.tags) key_name = "msoc-build" metadata_options { http_endpoint = "enabled" # checkov:skip=CKV_AWS_79:see tfsec explanation # tfsec:ignore:aws-ec2-enforce-http-token-imds Saltstack doesn't use s3 sources appropriately; see https://github.com/saltstack/salt/issues/60668 # tfsec:ignore:aws-autoscaling-enforce-http-token-imds http_tokens = "optional" } iam_instance_profile { name = aws_iam_instance_profile.portal_server_instance_profile.name } network_interfaces { delete_on_termination = true associate_public_ip_address = false security_groups = [data.aws_security_group.typical-host.id, aws_security_group.customer_portal.id] } block_device_mappings { device_name = "/dev/sda1" ebs { volume_type = "gp3" volume_size = "100" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn } } block_device_mappings { # swap device_name = "/dev/xvdm" ebs { volume_type = "gp3" volume_size = "8" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn # Snapshot IDs need to be grabbed from the ami, or it will replace every time. It's ugly. # This may prompt replacement when the AMI is updated. # See: # https://github.com/hashicorp/terraform/issues/19958 # https://github.com/terraform-providers/terraform-provider-aws/issues/13118 #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvdm"].ebs.snapshot_id } } block_device_mappings { # /home device_name = "/dev/xvdn" ebs { volume_type = "gp3" volume_size = "4" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvdn"].ebs.snapshot_id } } block_device_mappings { # /var device_name = "/dev/xvdo" ebs { volume_type = "gp3" volume_size = "15" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvdo"].ebs.snapshot_id } } block_device_mappings { # /var/tmp device_name = "/dev/xvdp" ebs { volume_type = "gp3" volume_size = "4" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvdp"].ebs.snapshot_id } } block_device_mappings { # /var/log device_name = "/dev/xvdq" ebs { volume_type = "gp3" volume_size = "8" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvdq"].ebs.snapshot_id } } block_device_mappings { # /var/log/audit device_name = "/dev/xvdr" ebs { volume_type = "gp3" volume_size = "8" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvdr"].ebs.snapshot_id } } block_device_mappings { # /tmp device_name = "/dev/xvds" ebs { volume_type = "gp3" volume_size = "4" delete_on_termination = true encrypted = true kms_key_id = data.aws_kms_key.ebs-key.arn #snapshot_id = local.block_device_mappings[local.ami_selection]["/dev/xvds"].ebs.snapshot_id } } tag_specifications { resource_type = "instance" tags = merge(var.tags, var.instance_tags, { "Name" : var.instance_name }) # This may have no effect? } tag_specifications { resource_type = "volume" tags = merge(var.tags, { "Name" : var.instance_name }) # This may have no effect } lifecycle { create_before_destroy = true } } resource "aws_autoscaling_group" "customer_portal" { name = "customer-portal-asg" launch_template { id = aws_launch_template.customer_portal.id version = "$Latest" } vpc_zone_identifier = var.private_subnets min_size = 1 max_size = 2 desired_capacity = 2 wait_for_capacity_timeout = 0 health_check_type = "EC2" tag { key = "Name" value = var.instance_name propagate_at_launch = true } # Must ignore changes to attachments, or tf will flip flop lifecycle { ignore_changes = [load_balancers, target_group_arns] } } # Render a multi-part cloud-init config making use of the part # above, and other source files data "template_cloudinit_config" "cloud-init" { gzip = true base64_encode = true # Main cloud-config configuration file. part { filename = "init.cfg" content_type = "text/cloud-config" content = templatefile("${path.module}/cloud-init/cloud-init.tpl", { zone = var.dns_info["private"]["zone"] environment = var.environment salt_master = local.salt_master proxy = local.proxy aws_partition = var.aws_partition aws_partition_alias = var.aws_partition_alias aws_region = var.aws_region } ) } # Additional parts as needed #part { # content_type = "text/x-shellscript" # content = "ffbaz" #} } #------------------------------------ # S3 Bucket What is this used for? Uncomment if needed. #------------------------------------ # resource "aws_s3_bucket" "customer-portal" { # bucket = "dps-customer-portal-${terraform.workspace}" # acl = "private" # tags = merge(local.standard_tags, var.tags, ) # } #---------------------------------------------------------------------------- # Portal Security Group #---------------------------------------------------------------------------- resource "aws_security_group" "customer_portal" { name = "customer_portal_http_inbound_sg" description = "Allow Customer Portal HTTP Inbound From ALB" vpc_id = var.vpc_id } #---------------------------------------------------------------------------- # INGRESS #---------------------------------------------------------------------------- resource "aws_security_group_rule" "customer_portal" { type = "ingress" description = "HTTPS - Inbound" from_port = 443 to_port = 443 protocol = "tcp" security_group_id = aws_security_group.customer_portal.id source_security_group_id = aws_security_group.customer_portal_alb.id } #---------------------------------------------------------------------------- # EGRESS #---------------------------------------------------------------------------- resource "aws_security_group_rule" "customer_portal_postgres_outbound" { type = "egress" description = "Postgres - Outbound" from_port = 5432 to_port = 5432 protocol = "tcp" security_group_id = aws_security_group.customer_portal.id source_security_group_id = aws_security_group.postgres.id } resource "aws_security_group_rule" "customer_portal_http_outbound" { type = "egress" description = "HTTP - Outbound" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr security_group_id = aws_security_group.customer_portal.id } resource "aws_security_group_rule" "customer_portal_https_outbound" { type = "egress" description = "HTTPS - Outbound" from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr security_group_id = aws_security_group.customer_portal.id } resource "aws_security_group_rule" "customer_portal_smtps_outbound" { type = "egress" description = "SMTPS - Outbound" from_port = 465 to_port = 465 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr security_group_id = aws_security_group.customer_portal.id } ### Output environment ID for purposes #output portal_env_id { # value = "${aws_elastic_beanstalk_environment.mdr-customer-portal-env.id}" #}